diff options
| author | Luc Donnet | 2016-11-14 21:15:31 +0100 |
|---|---|---|
| committer | Luc Donnet | 2016-11-14 21:15:31 +0100 |
| commit | 9cfa2309d53fa45342776f7cd2972080b3b85582 (patch) | |
| tree | aa435ae46f61fd25eee29a9e8a6c9beaf620a1d2 /app | |
| parent | 552611c5a96134eff8515bbfe32870e900225bfb (diff) | |
| parent | 3960264693d8ea79907b7c5619af678c69aef234 (diff) | |
| download | chouette-core-9cfa2309d53fa45342776f7cd2972080b3b85582.tar.bz2 | |
Merge branch 'master' of github.com:AF83/stif-boiv
Diffstat (limited to 'app')
74 files changed, 2364 insertions, 636 deletions
diff --git a/app/assets/javascripts/es6_browserified/actions/index.js b/app/assets/javascripts/es6_browserified/actions/index.js new file mode 100644 index 000000000..de3bfc113 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/actions/index.js @@ -0,0 +1,32 @@ +module.exports = { + addStop : () => { + return { + type: 'ADD_STOP' + } + }, + moveStopUp : (index) => { + return { + type: 'MOVE_STOP_UP', + index + } + }, + moveStopDown : (index) => { + return { + type: 'MOVE_STOP_DOWN', + index + } + }, + deleteStop: (index) => { + return { + type: 'DELETE_STOP', + index + } + }, + updateInputValue: (index, text) => { + return { + type : "UPDATE_INPUT_VALUE", + index, + text + } + } +} diff --git a/app/assets/javascripts/es6_browserified/components/App.js b/app/assets/javascripts/es6_browserified/components/App.js new file mode 100644 index 000000000..7488b0b39 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/components/App.js @@ -0,0 +1,12 @@ +var React = require('react') +var AddTodo = require('../containers/AddTodo') +var VisibleTodoList = require('../containers/VisibleTodoList') + +const App = () => ( + <div> + <AddTodo /> + <VisibleTodoList /> + </div> +) + +module.exports = App diff --git a/app/assets/javascripts/es6_browserified/components/BSelect2.js b/app/assets/javascripts/es6_browserified/components/BSelect2.js new file mode 100644 index 000000000..a78dc625f --- /dev/null +++ b/app/assets/javascripts/es6_browserified/components/BSelect2.js @@ -0,0 +1,127 @@ +var React = require('react') +var PropTypes = require('react').PropTypes +var Select2 = require('react-select2') + + +// get JSON full path +var origin = window.location.origin +var path = window.location.pathname.split('/', 3).join('/') + + +class BSelect3 extends React.Component{ + constructor(props) { + super(props) + this.state = { + edit: false + } + } + onToggleEdit(e) { + e.preventDefault() + this.setState({edit: !this.state.edit}) + } + onChange(e) { + this.props.onChange(this.props.index, { + text: e.currentTarget.textContent, stoparea_id: e.currentTarget.value + }) + this.setState({edit: false}) + } + + render() { + if(this.state.edit) + return ( + <div className='input-group select2-bootstrap-append'> + <BSelect2 {...this.props} onSelect={ this.onChange.bind(this) }/> + + <span className='input-group-btn'> + <button type='button' className='btn btn-default' onClick={this.onToggleEdit.bind(this)}> + <span className='fa fa-undo'></span> + </button> + </span> + </div> + ) + else + if(!this.props.value.stoparea_id) + return ( + <div> + <BSelect2 {...this.props} onSelect={ this.onChange.bind(this) }/> + </div> + ) + else + return ( + <div className='input-group'> + <a + className='form-control form-control-link' + href={origin + path + '/stop_areas/' + this.props.value.stoparea_id} + title={"Voir l'arrêt '" + this.props.value.text + "'"} + > + {this.props.value.text} + </a> + <span className='input-group-btn'> + <button type='button' className='btn btn-default' onClick={this.onToggleEdit.bind(this)}> + <span className='fa fa-pencil'></span> + </button> + </span> + </div> + ) + } +} + +class BSelect2 extends React.Component{ + componentDidMount() { + this.refs.newSelect.el.select2('open') + } + + render() { + return ( + <Select2 + value={ this.props.value.stoparea_id } + onSelect={ this.props.onSelect } + ref='newSelect' + options={{ + placeholder: 'Sélectionnez un arrêt existant...', + allowClear: true, + language: 'fr', /* Doesn't seem to work... :( */ + theme: 'bootstrap', + width: '100%', + ajax: { + url: origin + path + '/autocomplete_stop_areas.json', + dataType: 'json', + delay: '500', + data: function(params) { + return { + q: params.term + }; + }, + processResults: function(data, params) { + return { + results: data.map( + item => Object.assign( + {}, + item, + { text: item.name + ", " + item.zip_code + " " + item.short_city_name } + ) + ) + }; + }, + cache: true + }, + minimumInputLength: 3, + templateResult: formatRepo + }} + /> + ) + } +} + +const formatRepo = (props) => { + if(props.text) return props.text + // console.log(props) + // return ( + // <div> + // {props.short_name} + // <small><em>{props.zip_code} {props.short_city_name}</em></small> + // </div> + // ) +} + +module.exports = BSelect3 diff --git a/app/assets/javascripts/es6_browserified/components/Todo.js b/app/assets/javascripts/es6_browserified/components/Todo.js new file mode 100644 index 000000000..16e42eb3c --- /dev/null +++ b/app/assets/javascripts/es6_browserified/components/Todo.js @@ -0,0 +1,59 @@ +var React = require('react') +var PropTypes = require('react').PropTypes +var BSelect2 = require('./BSelect2') + +const Container = {display: 'table', width: '100%'} +const firstBlock = {display: 'table-cell', verticalAlign: 'middle'} +const secondBlock = {display: 'table-cell', verticalAlign: 'middle', width: 150, textAlign: 'right'} + +const Todo = (props) => { + return ( + <div className='list-group-item' style={Container}> + <div style={firstBlock}> + <div style={{display: 'inline-block', width: '10%', verticalAlign: 'middle', textAlign: 'right'}}> + <span className='label label-default' style={{marginRight: 10}}>{props.value.stoparea_id}</span> + </div> + + <div style={{display: 'inline-block', width: '90%', verticalAlign: 'middle'}}> + <BSelect2 id={'route_stop_points_' + props.id} value={props.value} onChange={props.onChange} index={props.index} /> + </div> + </div> + + <div style={secondBlock}> + <div className='btn-group btn-group-sm'> + <div + className={'btn btn-primary' + (props.first ? ' disabled' : '')} + onClick={props.onMoveUpClick} + > + <span className='fa fa-arrow-up'></span> + </div> + <div + className={'btn btn-primary' + (props.last ? ' disabled' : '')} + onClick={props.onMoveDownClick} + > + <span className='fa fa-arrow-down'></span> + </div> + <div + className='btn btn-danger' + onClick={props.onDeleteClick} + > + <span className='fa fa-trash'></span> + </div> + </div> + </div> + </div> + ) +} + +Todo.propTypes = { + onDeleteClick: PropTypes.func.isRequired, + onMoveUpClick: PropTypes.func.isRequired, + onMoveDownClick: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + first: PropTypes.bool, + last: PropTypes.bool, + index: PropTypes.number, + value: PropTypes.object +} + +module.exports = Todo diff --git a/app/assets/javascripts/es6_browserified/components/TodoList.js b/app/assets/javascripts/es6_browserified/components/TodoList.js new file mode 100644 index 000000000..e909f07bb --- /dev/null +++ b/app/assets/javascripts/es6_browserified/components/TodoList.js @@ -0,0 +1,34 @@ +var React = require('react') +var PropTypes = require('react').PropTypes +var Todo = require('./Todo') + +const TodoList = ({ todos, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange }) => { + return ( + <div className='list-group'> + {todos.map((todo, index) => + <Todo + key={'item-' + index} + onDeleteClick={() => onDeleteClick(index)} + onMoveUpClick={() => { + onMoveUpClick(index) + }} + onMoveDownClick={() => onMoveDownClick(index)} + onChange={ onChange } + first={ index === 0 } + last={ index === (todos.length - 1) } + index={ index } + value={ todo } + /> + )} + </div> + ) +} + +TodoList.propTypes = { + todos: PropTypes.array.isRequired, + onDeleteClick: PropTypes.func.isRequired, + onMoveUpClick: PropTypes.func.isRequired, + onMoveDownClick: PropTypes.func.isRequired +} + +module.exports = TodoList diff --git a/app/assets/javascripts/es6_browserified/containers/AddTodo.js b/app/assets/javascripts/es6_browserified/containers/AddTodo.js new file mode 100644 index 000000000..539b6f78e --- /dev/null +++ b/app/assets/javascripts/es6_browserified/containers/AddTodo.js @@ -0,0 +1,21 @@ +var React = require('react') +var connect = require('react-redux').connect +var addTodo = require('../actions').addStop + +let AddTodo = ({ dispatch }) => { + return ( + <div className="clearfix" style={{marginBottom: 10}}> + <form onSubmit={e => { + e.preventDefault() + dispatch(addTodo()) + }}> + <button type="submit" className="btn btn-primary btn-xs pull-right"> + <span className="fa fa-plus"></span> Ajouter un arrêt + </button> + </form> + </div> + ) +} +AddTodo = connect()(AddTodo) + +module.exports = AddTodo diff --git a/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js b/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js new file mode 100644 index 000000000..09da36060 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js @@ -0,0 +1,37 @@ +var connect = require('react-redux').connect +var toggleTodo = require('../actions').toggleTodo +var deleteStop = require('../actions').deleteStop +var moveStopUp = require('../actions').moveStopUp +var moveStopDown = require('../actions').moveStopDown +var handleChange = require('../actions').updateInputValue +var TodoList = require('../components/TodoList') + +const mapStateToProps = (state) => { + return { + todos: state.todos + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onDeleteClick: (index) =>{ + dispatch(deleteStop(index)) + }, + onMoveUpClick: (index) =>{ + dispatch(moveStopUp(index)) + }, + onMoveDownClick: (index) =>{ + dispatch(moveStopDown(index)) + }, + onChange: (index, text) =>{ + dispatch(handleChange(index, text)) + } + } +} + +const VisibleTodoList = connect( + mapStateToProps, + mapDispatchToProps +)(TodoList) + +module.exports = VisibleTodoList diff --git a/app/assets/javascripts/es6_browserified/form_helper.js b/app/assets/javascripts/es6_browserified/form_helper.js new file mode 100644 index 000000000..5888f23b9 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/form_helper.js @@ -0,0 +1,10 @@ +module.exports = { + addInput : (name, value, index) => { + let form = document.querySelector('form') + let input = document.createElement('input') + input.setAttribute('type', 'hidden') + input.setAttribute('name', `route[stop_points_attributes][${index}][${name}]`) + input.setAttribute('value', value) + form.appendChild(input) + } +} diff --git a/app/assets/javascripts/es6_browserified/reducers/index.js b/app/assets/javascripts/es6_browserified/reducers/index.js new file mode 100644 index 000000000..ae8423673 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/reducers/index.js @@ -0,0 +1,8 @@ +var combineReducers = require('redux').combineReducers +var todos = require('./todos') + +const todoApp = combineReducers({ + todos +}) + +module.exports = todoApp diff --git a/app/assets/javascripts/es6_browserified/reducers/todos.js b/app/assets/javascripts/es6_browserified/reducers/todos.js new file mode 100644 index 000000000..e46107efb --- /dev/null +++ b/app/assets/javascripts/es6_browserified/reducers/todos.js @@ -0,0 +1,73 @@ +var addInput = require('../form_helper').addInput + +const todo = (state = {}, action, length) => { + switch (action.type) { + case 'ADD_STOP': + return { + text: '', + index: length + } + case 'UPDATE_INPUT_VALUE': + console.log('reducer', action) + if (state.index !== action.index) { + return state + } + + return Object.assign( + {}, + state, + {text: action.text.text, stoparea_id: action.text.stoparea_id} + ) + default: + return state + } +} +const updateFormForDeletion = (stop) =>{ + if (stop.stoppoint_id !== undefined){ + let now = Date.now() + addInput('id', stop.stoppoint_id, now) + addInput('_destroy', 'true', now) + } +} + +const todos = (state = [], action) => { + switch (action.type) { + case 'ADD_STOP': + return [ + ...state, + todo(undefined, action, state.length) + ] + case 'MOVE_STOP_UP': + return [ + ...state.slice(0, action.index - 1), + state[action.index], + state[action.index - 1], + ...state.slice(action.index + 1) + ] + case 'MOVE_STOP_DOWN': + return [ + ...state.slice(0, action.index), + state[action.index + 1], + state[action.index], + ...state.slice(action.index + 2) + ] + case 'DELETE_STOP': + updateFormForDeletion(state[action.index]) + return [ + ...state.slice(0, action.index), + ...state.slice(action.index + 1).map((todo)=>{ + todo.index-- + return todo + }) + ] + case 'UPDATE_INPUT_VALUE': + return state.map((t, i) => (i === action.index) ? action.text : t) + // return state.map(t => + // todo(t, action) + // ) + default: + return state + } +} + +module.exports = todos diff --git a/app/assets/javascripts/es6_browserified/stop_points.js b/app/assets/javascripts/es6_browserified/stop_points.js new file mode 100644 index 000000000..7ecfd9253 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/stop_points.js @@ -0,0 +1,58 @@ +var React = require('react') +var render = require('react-dom').render +var Provider = require('react-redux').Provider +var createStore = require('redux').createStore +// var applyMiddleware = require('redux').applyMiddleware +var todoApp = require('./reducers') +var App = require('./components/App') +// var createLogger = require('redux-logger').default +// var thunkMiddleware = require('redux-thunk').default +// var promise = require('redux-promise') +var addInput = require('./form_helper').addInput + +const getInitialState = () => { + let state = [] + let datas = JSON.parse(decodeURIComponent(window.itinerary_stop)) + for (let [index, value] of datas.entries()){ + + let fancyText = value.name + if(value.zip_code && value.city_name) + fancyText += ", " + value.zip_code + " " + value.city_name + + state.push({ + stoppoint_id: value.stoppoint_id, + stoparea_id: value.stoparea_id, + index: index, + city_name: value.city_name, + zip_code: value.zip_code, + text: fancyText + }) + } + return state +} + +var initialState = {todos: getInitialState()} +// const loggerMiddleware = createLogger() +let store = createStore( + todoApp, + initialState + // applyMiddleware(thunkMiddleware, promise, loggerMiddleware) +) + +render( + <Provider store={store}> + <App /> + </Provider>, + document.getElementById('stop_points') +) + +document.querySelector('input[name=commit]').addEventListener('click', (event)=>{ + let state = store.getState() + for (let [i, todo] of state.todos.entries()){ + if (todo.stoppoint_id == undefined){ + todo.stoppoint_id = "" + } + addInput('id',todo.stoppoint_id, i) + addInput('stop_area_id',todo.stoparea_id, i) + } +}) diff --git a/app/assets/stylesheets/application.sass.erb b/app/assets/stylesheets/application.sass.erb index 53b767384..5a0927b9d 100644 --- a/app/assets/stylesheets/application.sass.erb +++ b/app/assets/stylesheets/application.sass.erb @@ -42,10 +42,16 @@ $body-bg: #eee @import 'vendor/typeahead' @import 'vendor/bootstrap_changes' @import 'vendor/simple_form' +// Select2 +@import 'vendor/select2' +@import 'vendor/select2-bootstrap' // Main css @import 'main/*' +// Components +@import 'components/*' + // Hack to make li simple li list-style: none diff --git a/app/assets/stylesheets/components/_form.sass b/app/assets/stylesheets/components/_form.sass new file mode 100644 index 000000000..d5f4a1eae --- /dev/null +++ b/app/assets/stylesheets/components/_form.sass @@ -0,0 +1,13 @@ +//-------// +// FORMS // +//-------// + +.form-control + &.form-control-link + &:hover, &:focus + // Reset default link styles + text-decoration: none + color: inherit + // Add custom + color: #555 + background-color: #f5f5f5 diff --git a/app/assets/stylesheets/vendor/bootstrap_changes.sass b/app/assets/stylesheets/vendor/bootstrap_changes.sass index 900949492..085f860a8 100644 --- a/app/assets/stylesheets/vendor/bootstrap_changes.sass +++ b/app/assets/stylesheets/vendor/bootstrap_changes.sass @@ -18,10 +18,10 @@ .validity_out color: $brand-danger - + .validity_out_soon color: $brand-warning - + .validity_regular color: $brand-success @@ -42,6 +42,14 @@ > ul margin: 0 padding: 0 - + > li - list-style: none !important
\ No newline at end of file + list-style: none !important + + +//-----------------------// +// Bootstrap-rails fixes // +//-----------------------// + +.input-group-btn > .btn + height: 34px diff --git a/app/assets/stylesheets/vendor/select2-bootstrap.css b/app/assets/stylesheets/vendor/select2-bootstrap.css new file mode 100644 index 000000000..99437f434 --- /dev/null +++ b/app/assets/stylesheets/vendor/select2-bootstrap.css @@ -0,0 +1,720 @@ +/*! + * Select2 Bootstrap Theme v0.1.0-beta.9 (https://select2.github.io/select2-bootstrap-theme) + * Copyright 2015-2016 Florian Kissling and contributors (https://github.com/select2/select2-bootstrap-theme/graphs/contributors) + * Licensed under MIT (https://github.com/select2/select2-bootstrap-theme/blob/master/LICENSE) + */ + +.select2-container--bootstrap { + display: block; + /*------------------------------------* #COMMON STYLES + \*------------------------------------*/ + /** + * Search field in the Select2 dropdown. + */ + /** + * No outline for all search fields - in the dropdown + * and inline in multi Select2s. + */ + /** + * Adjust Select2's choices hover and selected styles to match + * Bootstrap 3's default dropdown styles. + * + * @see http://getbootstrap.com/components/#dropdowns + */ + /** + * Clear the selection. + */ + /** + * Address disabled Select2 styles. + * + * @see https://select2.github.io/examples.html#disabled + * @see http://getbootstrap.com/css/#forms-control-disabled + */ + /*------------------------------------* #DROPDOWN + \*------------------------------------*/ + /** + * Dropdown border color and box-shadow. + */ + /** + * Limit the dropdown height. + */ + /*------------------------------------* #SINGLE SELECT2 + \*------------------------------------*/ + /*------------------------------------* #MULTIPLE SELECT2 + \*------------------------------------*/ + /** + * Address Bootstrap control sizing classes + * + * 1. Reset Bootstrap defaults. + * 2. Adjust the dropdown arrow button icon position. + * + * @see http://getbootstrap.com/css/#forms-control-sizes + */ + /* 1 */ + /*------------------------------------* #RTL SUPPORT + \*------------------------------------*/ +} + +.select2-container--bootstrap .select2-selection { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + background-color: #fff; + border: 1px solid #ccc; + border-radius: 4px; + color: #555555; + font-size: 14px; + outline: 0; +} + +.select2-container--bootstrap .select2-selection.form-control { + border-radius: 4px; +} + +.select2-container--bootstrap .select2-search--dropdown .select2-search__field { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + background-color: #fff; + border: 1px solid #ccc; + border-radius: 4px; + color: #555555; + font-size: 14px; +} + +.select2-container--bootstrap .select2-search__field { + outline: 0; + /* Firefox 18- */ + /** + * Firefox 19+ + * + * @see http://stackoverflow.com/questions/24236240/color-for-styled-placeholder-text-is-muted-in-firefox + */ +} + +.select2-container--bootstrap .select2-search__field::-webkit-input-placeholder { + color: #999; +} + +.select2-container--bootstrap .select2-search__field:-moz-placeholder { + color: #999; +} + +.select2-container--bootstrap .select2-search__field::-moz-placeholder { + color: #999; + opacity: 1; +} + +.select2-container--bootstrap .select2-search__field:-ms-input-placeholder { + color: #999; +} + +.select2-container--bootstrap .select2-results__option { + padding: 6px 12px; + /** + * Disabled results. + * + * @see https://select2.github.io/examples.html#disabled-results + */ + /** + * Hover state. + */ + /** + * Selected state. + */ +} + +.select2-container--bootstrap .select2-results__option[role=group] { + padding: 0; +} + +.select2-container--bootstrap .select2-results__option[aria-disabled=true] { + color: #777777; + cursor: not-allowed; +} + +.select2-container--bootstrap .select2-results__option[aria-selected=true] { + background-color: #f5f5f5; + color: #262626; +} + +.select2-container--bootstrap .select2-results__option--highlighted[aria-selected] { + background-color: #337ab7; + color: #fff; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option { + padding: 6px 12px; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__group { + padding-left: 0; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option { + margin-left: -12px; + padding-left: 24px; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -24px; + padding-left: 36px; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -36px; + padding-left: 48px; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -48px; + padding-left: 60px; +} + +.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -60px; + padding-left: 72px; +} + +.select2-container--bootstrap .select2-results__group { + color: #777777; + display: block; + padding: 6px 12px; + font-size: 12px; + line-height: 1.42857143; + white-space: nowrap; +} + +.select2-container--bootstrap.select2-container--focus .select2-selection, .select2-container--bootstrap.select2-container--open .select2-selection { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s; + border-color: #66afe9; +} + +.select2-container--bootstrap.select2-container--open { + /** + * Make the dropdown arrow point up while the dropdown is visible. + */ + /** + * Handle border radii of the container when the dropdown is showing. + */ +} + +.select2-container--bootstrap.select2-container--open .select2-selection .select2-selection__arrow b { + border-color: transparent transparent #999 transparent; + border-width: 0 4px 4px 4px; +} + +.select2-container--bootstrap.select2-container--open.select2-container--below .select2-selection { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + border-bottom-color: transparent; +} + +.select2-container--bootstrap.select2-container--open.select2-container--above .select2-selection { + border-top-right-radius: 0; + border-top-left-radius: 0; + border-top-color: transparent; +} + +.select2-container--bootstrap .select2-selection__clear { + color: #999; + cursor: pointer; + float: right; + font-weight: bold; + margin-right: 10px; +} + +.select2-container--bootstrap .select2-selection__clear:hover { + color: #333; +} + +.select2-container--bootstrap.select2-container--disabled .select2-selection { + border-color: #ccc; + -webkit-box-shadow: none; + box-shadow: none; +} + +.select2-container--bootstrap.select2-container--disabled .select2-selection, +.select2-container--bootstrap.select2-container--disabled .select2-search__field { + cursor: not-allowed; +} + +.select2-container--bootstrap.select2-container--disabled .select2-selection, +.select2-container--bootstrap.select2-container--disabled .select2-selection--multiple .select2-selection__choice { + background-color: #eeeeee; +} + +.select2-container--bootstrap.select2-container--disabled .select2-selection__clear, +.select2-container--bootstrap.select2-container--disabled .select2-selection--multiple .select2-selection__choice__remove { + display: none; +} + +.select2-container--bootstrap .select2-dropdown { + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + border-color: #66afe9; + overflow-x: hidden; + margin-top: -1px; +} + +.select2-container--bootstrap .select2-dropdown--above { + -webkit-box-shadow: 0px -6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0px -6px 12px rgba(0, 0, 0, 0.175); + margin-top: 1px; +} + +.select2-container--bootstrap .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; +} + +.select2-container--bootstrap .select2-selection--single { + height: 34px; + line-height: 1.42857143; + padding: 6px 24px 6px 12px; + /** + * Adjust the single Select2's dropdown arrow button appearance. + */ +} + +.select2-container--bootstrap .select2-selection--single .select2-selection__arrow { + position: absolute; + bottom: 0; + right: 12px; + top: 0; + width: 4px; +} + +.select2-container--bootstrap .select2-selection--single .select2-selection__arrow b { + border-color: #999 transparent transparent transparent; + border-style: solid; + border-width: 4px 4px 0 4px; + height: 0; + left: 0; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; +} + +.select2-container--bootstrap .select2-selection--single .select2-selection__rendered { + color: #555555; + padding: 0; +} + +.select2-container--bootstrap .select2-selection--single .select2-selection__placeholder { + color: #999; +} + +.select2-container--bootstrap .select2-selection--multiple { + min-height: 34px; + padding: 0; + height: auto; + /** + * Make Multi Select2's choices match Bootstrap 3's default button styles. + */ + /** + * Minus 2px borders. + */ + /** + * Clear the selection. + */ +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__rendered { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: block; + line-height: 1.42857143; + list-style: none; + margin: 0; + overflow: hidden; + padding: 0; + width: 100%; + text-overflow: ellipsis; + white-space: nowrap; +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__placeholder { + color: #999; + float: left; + margin-top: 5px; +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice { + color: #555555; + background: #fff; + border: 1px solid #ccc; + border-radius: 4px; + cursor: default; + float: left; + margin: 5px 0 0 6px; + padding: 0 6px; +} + +.select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field { + background: transparent; + padding: 0 12px; + height: 32px; + line-height: 1.42857143; + margin-top: 0; + min-width: 5em; +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice__remove { + color: #999; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 3px; +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #333; +} + +.select2-container--bootstrap .select2-selection--multiple .select2-selection__clear { + margin-top: 6px; +} + +.select2-container--bootstrap .select2-selection--single.input-sm, +.input-group-sm .select2-container--bootstrap .select2-selection--single, +.form-group-sm .select2-container--bootstrap .select2-selection--single { + border-radius: 3px; + font-size: 12px; + height: 30px; + line-height: 1.5; + padding: 5px 22px 5px 10px; + /* 2 */ +} + +.select2-container--bootstrap .select2-selection--single.input-sm .select2-selection__arrow b, +.input-group-sm .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b, +.form-group-sm .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b { + margin-left: -5px; +} + +.select2-container--bootstrap .select2-selection--multiple.input-sm, +.input-group-sm .select2-container--bootstrap .select2-selection--multiple, +.form-group-sm .select2-container--bootstrap .select2-selection--multiple { + min-height: 30px; + border-radius: 3px; +} + +.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-selection__choice, +.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice, +.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice { + font-size: 12px; + line-height: 1.5; + margin: 4px 0 0 5px; + padding: 0 5px; +} + +.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-search--inline .select2-search__field, +.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field, +.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field { + padding: 0 10px; + font-size: 12px; + height: 28px; + line-height: 1.5; +} + +.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-selection__clear, +.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear, +.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear { + margin-top: 5px; +} + +.select2-container--bootstrap .select2-selection--single.input-lg, +.input-group-lg .select2-container--bootstrap .select2-selection--single, +.form-group-lg .select2-container--bootstrap .select2-selection--single { + border-radius: 6px; + font-size: 18px; + height: 46px; + line-height: 1.3333333; + padding: 10px 31px 10px 16px; + /* 1 */ +} + +.select2-container--bootstrap .select2-selection--single.input-lg .select2-selection__arrow, +.input-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow, +.form-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow { + width: 5px; +} + +.select2-container--bootstrap .select2-selection--single.input-lg .select2-selection__arrow b, +.input-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b, +.form-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b { + border-width: 5px 5px 0 5px; + margin-left: -5px; + margin-left: -10px; + margin-top: -2.5px; +} + +.select2-container--bootstrap .select2-selection--multiple.input-lg, +.input-group-lg .select2-container--bootstrap .select2-selection--multiple, +.form-group-lg .select2-container--bootstrap .select2-selection--multiple { + min-height: 46px; + border-radius: 6px; +} + +.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-selection__choice, +.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice, +.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice { + font-size: 18px; + line-height: 1.3333333; + border-radius: 4px; + margin: 9px 0 0 8px; + padding: 0 10px; +} + +.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-search--inline .select2-search__field, +.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field, +.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field { + padding: 0 16px; + font-size: 18px; + height: 44px; + line-height: 1.3333333; +} + +.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-selection__clear, +.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear, +.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear { + margin-top: 10px; +} + +.select2-container--bootstrap .select2-selection.input-lg.select2-container--open .select2-selection--single { + /** + * Make the dropdown arrow point up while the dropdown is visible. + */ +} + +.select2-container--bootstrap .select2-selection.input-lg.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #999 transparent; + border-width: 0 5px 5px 5px; +} + +.input-group-lg .select2-container--bootstrap .select2-selection.select2-container--open .select2-selection--single { + /** + * Make the dropdown arrow point up while the dropdown is visible. + */ +} + +.input-group-lg .select2-container--bootstrap .select2-selection.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #999 transparent; + border-width: 0 5px 5px 5px; +} + +.select2-container--bootstrap[dir="rtl"] { + /** + * Single Select2 + * + * 1. Makes sure that .select2-selection__placeholder is positioned + * correctly. + */ + /** + * Multiple Select2 + */ +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--single { + padding-left: 24px; + padding-right: 12px; +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__rendered { + padding-right: 0; + padding-left: 0; + text-align: right; + /* 1 */ +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__arrow { + left: 12px; + right: auto; +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__arrow b { + margin-left: 0; +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice, +.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder { + float: right; +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 0; + margin-right: 6px; +} + +.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; +} + +/*------------------------------------* #ADDITIONAL GOODIES +\*------------------------------------*/ +/** + * Address Bootstrap's validation states + * + * If a Select2 widget parent has one of Bootstrap's validation state modifier + * classes, adjust Select2's border colors and focus states accordingly. + * You may apply said classes to the Select2 dropdown (body > .select2-container) + * via JavaScript match Bootstraps' to make its styles match. + * + * @see http://getbootstrap.com/css/#forms-control-validation + */ +.has-warning .select2-dropdown, +.has-warning .select2-selection { + border-color: #8a6d3b; +} + +.has-warning .select2-container--focus .select2-selection, +.has-warning .select2-container--open .select2-selection { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b; + border-color: #66512c; +} + +.has-warning.select2-drop-active { + border-color: #66512c; +} + +.has-warning.select2-drop-active.select2-drop.select2-drop-above { + border-top-color: #66512c; +} + +.has-error .select2-dropdown, +.has-error .select2-selection { + border-color: #a94442; +} + +.has-error .select2-container--focus .select2-selection, +.has-error .select2-container--open .select2-selection { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + border-color: #843534; +} + +.has-error.select2-drop-active { + border-color: #843534; +} + +.has-error.select2-drop-active.select2-drop.select2-drop-above { + border-top-color: #843534; +} + +.has-success .select2-dropdown, +.has-success .select2-selection { + border-color: #3c763d; +} + +.has-success .select2-container--focus .select2-selection, +.has-success .select2-container--open .select2-selection { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168; + border-color: #2b542c; +} + +.has-success.select2-drop-active { + border-color: #2b542c; +} + +.has-success.select2-drop-active.select2-drop.select2-drop-above { + border-top-color: #2b542c; +} + +/** + * Select2 widgets in Bootstrap Input Groups + * + * When Select2 widgets are combined with other elements using Bootstraps + * "Input Group" component, we don't want specific edges of the Select2 + * container to have a border-radius. + * + * Use .select2-bootstrap-prepend and .select2-bootstrap-append on + * a Bootstrap 3 .input-group to let the contained Select2 widget know which + * edges should not be rounded as they are directly followed by another element. + * + * @see http://getbootstrap.com/components/#input-groups + */ +/** + * Mimick Bootstraps .input-group .form-control styles. + * + * @see https://github.com/twbs/bootstrap/blob/master/less/input-groups.less + */ +.input-group .select2-container--bootstrap { + display: table; + table-layout: fixed; + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; + /** + * Adjust z-index like Bootstrap does to show the focus-box-shadow + * above appended buttons in .input-group and .form-group. + */ +} + +.input-group .select2-container--bootstrap.select2-container--open, .input-group .select2-container--bootstrap.select2-container--focus { + z-index: 3; +} + +.input-group.select2-bootstrap-prepend .select2-container--bootstrap .select2-selection { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.input-group.select2-bootstrap-append .select2-container--bootstrap .select2-selection { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +/** + * Adjust alignment of Bootstrap buttons in Bootstrap Input Groups to address + * Multi Select2's height which - depending on how many elements have been selected - + * may grow taller than its initial size. + * + * @see http://getbootstrap.com/components/#input-groups + */ +.select2-bootstrap-append .select2-container--bootstrap, +.select2-bootstrap-append .input-group-btn, +.select2-bootstrap-append .input-group-btn .btn, +.select2-bootstrap-prepend .select2-container--bootstrap, +.select2-bootstrap-prepend .input-group-btn, +.select2-bootstrap-prepend .input-group-btn .btn { + vertical-align: top; +} + +/** + * Temporary fix for https://github.com/select2/select2-bootstrap-theme/issues/9 + * + * Provides `!important` for certain properties of the class applied to the + * original `<select>` element to hide it. + * + * @see https://github.com/select2/select2/pull/3301 + * @see https://github.com/fk/select2/commit/31830c7b32cb3d8e1b12d5b434dee40a6e753ada + */ +.form-control.select2-hidden-accessible { + position: absolute !important; + width: 1px !important; +} + +/** + * Display override for inline forms + */ +.form-inline .select2-container--bootstrap { + display: inline-block; +} diff --git a/app/assets/stylesheets/vendor/select2.css b/app/assets/stylesheets/vendor/select2.css new file mode 100644 index 000000000..6f3cb138d --- /dev/null +++ b/app/assets/stylesheets/vendor/select2.css @@ -0,0 +1,498 @@ +.select2-container { + box-sizing: border-box; + display: inline-block; + margin: 0; + position: relative; + vertical-align: middle; } + .select2-container .select2-selection--single { + box-sizing: border-box; + cursor: pointer; + display: block; + height: 28px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--single .select2-selection__rendered { + display: block; + padding-left: 8px; + padding-right: 20px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-selection--single .select2-selection__clear { + position: relative; } + .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { + padding-right: 8px; + padding-left: 20px; } + .select2-container .select2-selection--multiple { + box-sizing: border-box; + cursor: pointer; + display: block; + min-height: 32px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--multiple .select2-selection__rendered { + display: inline-block; + overflow: hidden; + padding-left: 8px; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-search--inline { + float: left; } + .select2-container .select2-search--inline .select2-search__field { + box-sizing: border-box; + border: none; + font-size: 100%; + margin-top: 5px; + padding: 0; } + .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + +.select2-dropdown { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + box-sizing: border-box; + display: block; + position: absolute; + left: -100000px; + width: 100%; + z-index: 1051; } + +.select2-results { + display: block; } + +.select2-results__options { + list-style: none; + margin: 0; + padding: 0; } + +.select2-results__option { + padding: 6px; + user-select: none; + -webkit-user-select: none; } + .select2-results__option[aria-selected] { + cursor: pointer; } + +.select2-container--open .select2-dropdown { + left: 0; } + +.select2-container--open .select2-dropdown--above { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--open .select2-dropdown--below { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-search--dropdown { + display: block; + padding: 4px; } + .select2-search--dropdown .select2-search__field { + padding: 4px; + width: 100%; + box-sizing: border-box; } + .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + .select2-search--dropdown.select2-search--hide { + display: none; } + +.select2-close-mask { + border: 0; + margin: 0; + padding: 0; + display: block; + position: fixed; + left: 0; + top: 0; + min-height: 100%; + min-width: 100%; + height: auto; + width: auto; + opacity: 0; + z-index: 99; + background-color: #fff; + filter: alpha(opacity=0); } + +.select2-hidden-accessible { + border: 0 !important; + clip: rect(0 0 0 0) !important; + height: 1px !important; + margin: -1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; } + +.select2-container--default .select2-selection--single { + background-color: #fff; + border: 1px solid #aaa; + border-radius: 4px; } + .select2-container--default .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--default .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; } + .select2-container--default .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--default .select2-selection--single .select2-selection__arrow { + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; } + .select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { + left: 1px; + right: auto; } + +.select2-container--default.select2-container--disabled .select2-selection--single { + background-color: #eee; + cursor: default; } + .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { + display: none; } + +.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--default .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered { + box-sizing: border-box; + list-style: none; + margin: 0; + padding: 0 5px; + width: 100%; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered li { + list-style: none; } + .select2-container--default .select2-selection--multiple .select2-selection__placeholder { + color: #999; + margin-top: 5px; + float: left; } + .select2-container--default .select2-selection--multiple .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-top: 5px; + margin-right: 10px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: #999; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #333; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { + float: right; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 5px; + margin-right: auto; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--default.select2-container--focus .select2-selection--multiple { + border: solid black 1px; + outline: 0; } + +.select2-container--default.select2-container--disabled .select2-selection--multiple { + background-color: #eee; + cursor: default; } + +.select2-container--default.select2-container--disabled .select2-selection__choice__remove { + display: none; } + +.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--default .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; } + +.select2-container--default .select2-search--inline .select2-search__field { + background: transparent; + border: none; + outline: 0; + box-shadow: none; + -webkit-appearance: textfield; } + +.select2-container--default .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--default .select2-results__option[role=group] { + padding: 0; } + +.select2-container--default .select2-results__option[aria-disabled=true] { + color: #999; } + +.select2-container--default .select2-results__option[aria-selected=true] { + background-color: #ddd; } + +.select2-container--default .select2-results__option .select2-results__option { + padding-left: 1em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__group { + padding-left: 0; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option { + margin-left: -1em; + padding-left: 2em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -2em; + padding-left: 3em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -3em; + padding-left: 4em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -4em; + padding-left: 5em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -5em; + padding-left: 6em; } + +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background-color: #5897fb; + color: white; } + +.select2-container--default .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic .select2-selection--single { + background-color: #f7f7f7; + border: 1px solid #aaa; + border-radius: 4px; + outline: 0; + background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + .select2-container--classic .select2-selection--single:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--classic .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-right: 10px; } + .select2-container--classic .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--classic .select2-selection--single .select2-selection__arrow { + background-color: #ddd; + border: none; + border-left: 1px solid #aaa; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } + .select2-container--classic .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { + border: none; + border-right: 1px solid #aaa; + border-radius: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + left: 1px; + right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--single { + border: 1px solid #5897fb; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { + background: transparent; + border: none; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; + background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } + +.select2-container--classic .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; + outline: 0; } + .select2-container--classic .select2-selection--multiple:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--multiple .select2-selection__rendered { + list-style: none; + margin: 0; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__clear { + display: none; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { + color: #888; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #555; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + float: right; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 5px; + margin-right: auto; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--multiple { + border: 1px solid #5897fb; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--classic .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; + outline: 0; } + +.select2-container--classic .select2-search--inline .select2-search__field { + outline: 0; + box-shadow: none; } + +.select2-container--classic .select2-dropdown { + background-color: white; + border: 1px solid transparent; } + +.select2-container--classic .select2-dropdown--above { + border-bottom: none; } + +.select2-container--classic .select2-dropdown--below { + border-top: none; } + +.select2-container--classic .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--classic .select2-results__option[role=group] { + padding: 0; } + +.select2-container--classic .select2-results__option[aria-disabled=true] { + color: grey; } + +.select2-container--classic .select2-results__option--highlighted[aria-selected] { + background-color: #3875d7; + color: white; } + +.select2-container--classic .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic.select2-container--open .select2-dropdown { + border-color: #5897fb; } + +/* Do the shit, dude */ +.select2-container .select2-results__options .select2-results__option.select2-results__message { + display: none; +} +.select2-container .select2-results__options .select2-results__option.loading-results { + font-size: 0; +} +.select2-container .select2-results__options .select2-results__option.loading-results::before { + content: "Recherche en cours..."; + font-size: 14px; + font-style: italic; + display: inline; +} diff --git a/app/controllers/api/v1/routes_controller.rb b/app/controllers/api/v1/routes_controller.rb index e3694725f..fbc589355 100644 --- a/app/controllers/api/v1/routes_controller.rb +++ b/app/controllers/api/v1/routes_controller.rb @@ -3,11 +3,11 @@ class Api::V1::RoutesController < Api::V1::ChouetteController defaults :resource_class => Chouette::Route, :finder => :find_by_objectid! belongs_to :line, :parent_class => Chouette::Line, :optional => true, :finder => :find_by_objectid!, :param => :line_id - + protected def collection @routes ||= parent.routes - end + end end diff --git a/app/controllers/clean_ups_controller.rb b/app/controllers/clean_ups_controller.rb index 8718fc0dc..c6e4ecd44 100644 --- a/app/controllers/clean_ups_controller.rb +++ b/app/controllers/clean_ups_controller.rb @@ -1,23 +1,19 @@ class CleanUpsController < ChouetteController respond_to :html, :only => [:create] - belongs_to :referential def create - clean_up = CleanUp.new(params[:clean_up]) - - if clean_up.invalid? - flash[:alert] = clean_up.errors.full_messages.join("<br/>") + clean_up = CleanUp.new(clean_up_params) + clean_up.referential = @referential + if clean_up.valid? + clean_up.save else - begin - result = clean_up.clean - flash[:notice] = result.notice.join("<br/>") - rescue => e - Rails.logger.error "CleanUp failed : #{e} #{e.backtrace}" - flash[:alert] = t('clean_ups.failure', error_message: e.to_s) - end + flash[:alert] = clean_up.errors.full_messages.join("<br/>") end redirect_to referential_path(@referential) end + def clean_up_params + params.require(:clean_up).permit(:keep_lines, :keep_stops, :keep_companies, :keep_networks, :keep_group_of_lines, :expected_date) + end end diff --git a/app/controllers/referential_companies_controller.rb b/app/controllers/referential_companies_controller.rb index 104deba9f..a369488ba 100644 --- a/app/controllers/referential_companies_controller.rb +++ b/app/controllers/referential_companies_controller.rb @@ -27,7 +27,7 @@ class ReferentialCompaniesController < ChouetteController end def collection - @q = referential.companies.search(params[:q]) + @q = referential.workbench.companies.search(params[:q]) @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) end diff --git a/app/controllers/referential_group_of_lines_controller.rb b/app/controllers/referential_group_of_lines_controller.rb index d40fd6090..4decef558 100644 --- a/app/controllers/referential_group_of_lines_controller.rb +++ b/app/controllers/referential_group_of_lines_controller.rb @@ -55,7 +55,7 @@ class ReferentialGroupOfLinesController < ChouetteController end def collection - @q = referential.group_of_lines.search(params[:q]) + @q = referential.workbench.group_of_lines.search(params[:q]) @group_of_lines ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) end diff --git a/app/controllers/referential_networks_controller.rb b/app/controllers/referential_networks_controller.rb index 2d3f4ad6b..00c680c65 100644 --- a/app/controllers/referential_networks_controller.rb +++ b/app/controllers/referential_networks_controller.rb @@ -35,7 +35,7 @@ class ReferentialNetworksController < ChouetteController end def collection - @q = referential.networks.search(params[:q]) + @q = referential.workbench.networks.search(params[:q]) @networks ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) end diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index 3ae59f975..003c85d3a 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -57,11 +57,7 @@ class ReferentialsController < BreadcrumbController end def create_resource(referential) - if referential.created_from - referential.clone_association referential.created_from - else - referential.organisation = current_organisation - end + referential.organisation = current_organisation unless referential.created_from super end diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 59c129867..a7e8e32a6 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -77,7 +77,7 @@ class RoutesController < ChouetteController private def route_params - params.require(:route).permit( :direction_code, :wayback_code, :line_id, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :opposite_route_id, :published_name, :number, :direction, :wayback, { stop_points_attributes: [ :id, :_destroy, :position, :stop_area_id, :for_boarding, :for_alighting ] } ) + params.require(:route).permit( :line_id, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :opposite_route_id, :published_name, :number, :direction, :wayback, { stop_points_attributes: [ :id, :_destroy, :position, :stop_area_id, :for_boarding, :for_alighting ] } ) end end diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index 8f6a1565a..1f55b1de8 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -26,6 +26,7 @@ class StopAreasController < BreadcrumbController end def add_children + authorize stop_area @stop_area = stop_area @children = stop_area.children build_breadcrumb :edit diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb index b3d79262e..71017fd13 100644 --- a/app/helpers/routes_helper.rb +++ b/app/helpers/routes_helper.rb @@ -6,11 +6,15 @@ module RoutesHelper end def fonticon_wayback(wayback) - if wayback == "A" + if wayback == 'straight_forward' return '<i class="fa fa-arrow-right"></i>'.html_safe else - return '<i class="fa fa-arrow-left"></i>'.html_safe + return '<i class="fa fa-arrow-left"></i>'.html_safe end end - + + def route_json_for_edit(route) + route.stop_points.includes(:stop_area).map { |s| s.stop_area.attributes.slice("name","city_name", "zip_code").merge(stoppoint_id: s.id, stoparea_id: s.stop_area.id) }.to_json + end + end diff --git a/app/inputs/search_stop_area_input.rb b/app/inputs/search_stop_area_input.rb index e5cfafc34..c7e21e921 100644 --- a/app/inputs/search_stop_area_input.rb +++ b/app/inputs/search_stop_area_input.rb @@ -1,5 +1,5 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput - + def search if options[:json] tokenLimit = options[:tokenLimit].present? ? options[:tokenLimit] : "null" @@ -16,19 +16,19 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput var item_localization = function( item){ var localization = item.zip_code + ' ' + item.short_city_name; - return localization; + return localization; }; - var item_format = function( item ){ - var name = item_name( item ); + var item_format = function( item ){ + var name = item_name( item ); var localization = item_localization( item ); - + html_result = '<li>'; html_result += '<span><image src=\"' + item.stop_area_path + '\" height=\"25px\" width=\"25px\"></span>' if(name != '') { - html_result += '<span style=\"height:25px; line-height:25px; margin-left: 5px; \">' + name + '</span>' ; - } + html_result += '<span style=\"height:25px; line-height:25px; margin-left: 5px; \">' + name + '</span>' ; + } if(localization != '') { html_result += '<small style=\"height:25px; line-height:25px; margin-left: 10px; color: #555; \">' + localization + '</small>'; @@ -48,7 +48,7 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput noResultsText: '#{options[:no_result_text]}', searchingText: '#{options[:searching_text]}', resultsFormatter: item_format, - tokenFormatter: item_format, + tokenFormatter: item_format, }); });").html_safe) end @@ -62,7 +62,7 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput end end - def input_html_options + def input_html_options css_class = super[:class] super.merge({ :required => nil, diff --git a/app/models/chouette/for_alighting_enumerations.rb b/app/models/chouette/for_alighting_enumerations.rb index 4f34927d3..ab07a670d 100644 --- a/app/models/chouette/for_alighting_enumerations.rb +++ b/app/models/chouette/for_alighting_enumerations.rb @@ -2,7 +2,7 @@ module Chouette module ForAlightingEnumerations extend Enumerize extend ActiveModel::Naming - + enumerize :for_alighting, in: %w[normal forbidden request_stop is_flexible] end end diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 8949a6bc2..446eb5f70 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -1,14 +1,17 @@ class Chouette::Route < Chouette::TridentActiveRecord include RouteRestrictions + extend Enumerize + extend ActiveModel::Naming + + enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east) + enumerize :wayback, in: %i(straight_forward backward) + # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" - attr_accessor :wayback_code - attr_accessor :direction_code - def self.nullable_attributes - [:published_name, :comment, :number, :name] + [:published_name, :comment, :number, :name, :direction, :wayback] end belongs_to :line @@ -61,8 +64,11 @@ class Chouette::Route < Chouette::TridentActiveRecord # validates_presence_of :name validates_presence_of :line - # validates_presence_of :direction_code - # validates_presence_of :wayback_code + # validates_presence_of :direction + # validates_presence_of :wayback + + validates :direction, inclusion: { in: self.direction.values } + validates :wayback, inclusion: { in: self.wayback.values } before_destroy :dereference_opposite_route @@ -96,52 +102,6 @@ class Chouette::Route < Chouette::TridentActiveRecord .order( "vehicle_journey_at_stops.departure_time") end - def self.direction_binding - { "A" => "straight_forward", - "R" => "backward", - "ClockWise" => "clock_wise", - "CounterClockWise" => "counter_clock_wise", - "North" => "north", - "NorthWest" => "north_west", - "West" => "west", - "SouthWest" => "south_west", - "South" => "south", - "SouthEast" => "south_east", - "East" => "east", - "NorthEast" => "north_east"} - end - def direction_code - return nil if self.class.direction_binding[direction].nil? - Chouette::Direction.new( self.class.direction_binding[direction]) - end - def direction_code=(direction_code) - self.direction = nil - self.class.direction_binding.each do |k,v| - self.direction = k if v==direction_code - end - end - @@directions = nil - def self.directions - @@directions ||= Chouette::Direction.all - end - def self.wayback_binding - { "A" => "straight_forward", "R" => "backward"} - end - def wayback_code - return nil if self.class.wayback_binding[wayback].nil? - Chouette::Wayback.new( self.class.wayback_binding[wayback]) - end - def wayback_code=(wayback_code) - self.wayback = nil - self.class.wayback_binding.each do |k,v| - self.wayback = k if v==wayback_code - end - end - @@waybacks = nil - def self.waybacks - @@waybacks ||= Chouette::Wayback.all - end - def stop_point_permutation?( stop_point_ids) stop_points.map(&:id).map(&:to_s).sort == stop_point_ids.map(&:to_s).sort end diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb index 1a03b0fb1..986fbdd24 100644 --- a/app/models/clean_up.rb +++ b/app/models/clean_up.rb @@ -1,151 +1,121 @@ -class CleanUp - include ActiveModel::Validations - include ActiveModel::Conversion - extend ActiveModel::Naming +class CleanUp < ActiveRecord::Base + include AASM + belongs_to :referential + validates :expected_date, presence: true + after_commit :perform_cleanup, :on => :create + + def perform_cleanup + CleanUpWorker.perform_async(self.id) + end + + aasm column: :status do + state :new, :initial => true + state :pending + state :successful + state :failed - attr_accessor :expected_date, :keep_lines, :keep_stops , :keep_companies - attr_accessor :keep_networks, :keep_group_of_lines + event :run, after: :update_started_at do + transitions :from => [:new, :failed], :to => :pending + end - validates_presence_of :expected_date + event :successful, after: :update_ended_at do + transitions :from => [:pending, :failed], :to => :successful + end - def initialize(attributes = {}) - attributes.each do |name, value| - send("#{name}=", value) + event :failed, after: :update_ended_at do + transitions :from => :pending, :to => :failed end end - def persisted? - false + def update_started_at + update_attribute(:started_at, Time.now) end - def vehicle_journeys - Chouette::VehicleJourney.where "id not in (select distinct vehicle_journey_id from time_tables_vehicle_journeys)" + def update_ended_at + update_attribute(:ended_at, Time.now) end - def journey_patterns - Chouette::JourneyPattern.where "id not in (select distinct journey_pattern_id from vehicle_journeys)" + def clean + # as foreign keys are presents , delete method can be used for faster performance + # find and remove time_tables + result = CleanUpResult.new + tms = Chouette::TimeTable.validity_out_from_on?(expected_date) + result.time_table_count = tms.size + tms.each.map(&:delete) + + result.vehicle_journey_count = self.clean_vehicle_journeys + result.journey_pattern_count = self.clean_journey_patterns + result.route_count = self.clean_routes + result.line_count = self.clean_lines unless keep_lines + + unless keep_stops + result.stop_count += self.clean_physical_stop_areas + result.stop_count += self.clean_commercial_stop_areas + result.stop_count += self.clean_stop_place_stop_areas + result.stop_count += self.clean_itl_stop_areas + end + + # If asked remove companies without lines or vehicle journeys + result.company_count = self.clean_companies unless keep_companies + # If asked remove networks without lines + result.network_count = self.clean_networks unless keep_networks + # If asked remove group_of_lines without lines + result.group_of_line_count = self.clean_group_of_lines unless keep_group_of_lines + result end - def routes - Chouette::Route.where "id not in (select distinct route_id from journey_patterns)" + def clean_physical_stop_areas + ids = Chouette::StopArea.physical.includes(:stop_points).where(:stop_points => {id: nil}).pluck(:id) + Chouette::StopArea.physical.where(id: ids).delete_all end - def lines - Chouette::Line.where "id not in (select distinct line_id from routes)" + def clean_commercial_stop_areas + ids = Chouette::StopArea.commercial.where.not(parent_id: nil).pluck(:parent_id) + Chouette::StopArea.commercial.where.not(id: ids).delete_all end - def physical_stop_areas - Chouette::StopArea.physical + def clean_stop_place_stop_areas + ids = Chouette::StopArea.stop_place.includes(:stop_points).where(:stop_points => {id: nil}).pluck(:id) + Chouette::StopArea.stop_place.where(id: ids).delete_all end - def commercial_stop_areas - Chouette::StopArea.commercial + def clean_itl_stop_areas + ids = Chouette::StopArea.itl.includes(:stop_points).where(:stop_points => {id: nil}).pluck(:id) + Chouette::StopArea.itl.where(id: ids).delete_all end - def stop_place_stop_areas - Chouette::StopArea.stop_place + def clean_vehicle_journeys + ids = Chouette::VehicleJourney.includes(:time_tables).where(:time_tables => {id: nil}).pluck(:id) + Chouette::VehicleJourney.where(id: ids).delete_all end - def itl_stop_areas - Chouette::StopArea.itl + def clean_lines + ids = Chouette::Line.includes(:routes).where(:routes => {id: nil}).pluck(:id) + Chouette::Line.where(id: ids).delete_all end - def clean - # as foreign keys are presents , delete method can be used for faster performance - result = CleanUpResult.new - # find and remove time_tables - tms = Chouette::TimeTable.validity_out_from_on?(Date.parse(expected_date)) - result.time_table_count = tms.size - tms.each do |tm| - tm.delete - end - # remove vehiclejourneys without timetables - vehicle_journeys.find_each do |vj| - if vj.time_tables.size == 0 - result.vehicle_journey_count += 1 - vj.delete - end - end - # remove journeypatterns without vehicle journeys - journey_patterns.find_each do |jp| - if jp.vehicle_journeys.size == 0 - result.journey_pattern_count += 1 - jp.delete - end - end - # remove routes without journeypatterns - routes.find_each do |r| - if r.journey_patterns.size == 0 - result.route_count += 1 - r.delete - end - end - # if asked remove lines without routes - if keep_lines == "0" - lines.find_each do |l| - if l.routes.size == 0 - result.line_count += 1 - l.delete - end - end - end - # if asked remove stops without children (recurse) - if keep_stops == "0" - physical_stop_areas.find_each do |bp| - if bp.stop_points.size == 0 - result.stop_count += 1 - bp.delete - end - end - commercial_stop_areas.find_each do |csp| - if csp.children.size == 0 - result.stop_count += 1 - csp.delete - end - end - stop_place_stop_areas.find_each do |sp| - if sp.children.size == 0 - result.stop_count += 1 - sp.delete - end - end - itl_stop_areas.find_each do |itl| - if itl.routing_stops.size == 0 - result.stop_count += 1 - itl.delete - end - end - end - # if asked remove companies without lines or vehicle journeys - if keep_companies == "0" - Chouette::Company.find_each do |c| - if c.lines.size == 0 - result.company_count += 1 - c.delete - end - end - end + def clean_routes + ids = Chouette::Route.includes(:journey_patterns).where(:journey_patterns => {id: nil}).pluck(:id) + Chouette::Route.where(id: ids).delete_all + end - # if asked remove networks without lines - if keep_networks == "0" - Chouette::Network.find_each do |n| - if n.lines.size == 0 - result.network_count += 1 - n.delete - end - end - end + def clean_journey_patterns + ids = Chouette::JourneyPattern.includes(:vehicle_journeys).where(:vehicle_journeys => {id: nil}).pluck(:id) + Chouette::JourneyPattern.where(id: ids).delete_all + end - # if asked remove group_of_lines without lines - if keep_group_of_lines == "0" - Chouette::GroupOfLine.find_each do |n| - if n.lines.size == 0 - result.group_of_line_count += 1 - n.delete - end - end - end - result + def clean_companies + ids = Chouette::Company.includes(:lines).where(:lines => {id: nil}).pluck(:id) + Chouette::Company.where(id: ids).delete_all + end + + def clean_networks + ids = Chouette::Network.includes(:lines).where(:lines => {id: nil}).pluck(:id) + Chouette::Network.where(id: ids).delete_all end + def clean_group_of_lines + ids = Chouette::GroupOfLine.includes(:lines).where(:lines => {id: nil}).pluck(:id) + Chouette::GroupOfLine.where(id: ids).delete_all + end end diff --git a/app/models/concerns/route_restrictions.rb b/app/models/concerns/route_restrictions.rb index 5a098d86f..4a21cbccf 100644 --- a/app/models/concerns/route_restrictions.rb +++ b/app/models/concerns/route_restrictions.rb @@ -8,7 +8,7 @@ module RouteRestrictions # HUB-37 def wayback_code_limitation return unless hub_restricted? - errors.add( :wayback_code, I18n.t('hub.routes.wayback_code_exclusive')) if line.routes.reject {|r| r.id==id}.map(&:wayback_code).include?( wayback_code) + errors.add( :wayback, I18n.t('hub.routes.wayback_code_exclusive')) if line.routes.reject {|r| r.id==id}.map(&:wayback).include?( wayback) end # HUB-37 diff --git a/app/models/line_referential.rb b/app/models/line_referential.rb index 7d3b638cb..7096fd6ff 100644 --- a/app/models/line_referential.rb +++ b/app/models/line_referential.rb @@ -6,7 +6,7 @@ class LineReferential < ActiveRecord::Base has_many :group_of_lines, class_name: 'Chouette::GroupOfLine' has_many :companies, class_name: 'Chouette::Company' has_many :networks, class_name: 'Chouette::Network' - has_many :line_referential_syncs, -> { order created_at: :desc} + has_many :line_referential_syncs, -> { order created_at: :desc } has_many :workbenches def add_member(organisation, options = {}) @@ -26,4 +26,8 @@ class LineReferential < ActiveRecord::Base def last_sync line_referential_syncs.last end + + def transport_modes + Chouette::TransportMode.all.select { |tm| tm.positive? } + end end diff --git a/app/models/line_referential_sync_message.rb b/app/models/line_referential_sync_message.rb index c62b77689..da9db4095 100644 --- a/app/models/line_referential_sync_message.rb +++ b/app/models/line_referential_sync_message.rb @@ -1,6 +1,6 @@ class LineReferentialSyncMessage < ActiveRecord::Base belongs_to :line_referential_sync - enum criticity: [:info, :warn, :error] + enum criticity: [:info, :warning, :danger] validates :criticity, presence: true end diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 86386772c..4d93b0ba6 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -14,7 +14,8 @@ class Organisation < ActiveRecord::Base has_many :workbenches - validates :name, :presence => true, :uniqueness => true + validates_presence_of :name + validates_uniqueness_of :code after_create :add_rule_parameter_set @@ -39,20 +40,23 @@ class Organisation < ActiveRecord::Base end end + def self.sync_update code, name, scope + org = Organisation.find_or_initialize_by(code: code) + if scope + org.sso_attributes ||= {} + org.sso_attributes['functional_scope'] = scope + org.sso_attributes_will_change! + end + org.name = name + org.synced_at = Time.now + org.save + org + end + def self.portail_sync self.portail_api_request.each do |el| - Organisation.find_or_create_by(code: el['code']).tap do |org| - org.name = el['name'] - if el['functional_scope'] - org.sso_attributes ||= {} - org.sso_attributes[:functional_scope] = el['functional_scope'].delete('\\"') - end - if org.changed? - org.synced_at = Time.now - org.save - puts "✓ Organisation #{org.name} has been updated" unless Rails.env.test? - end - end + org = self.sync_update el['code'], el['name'], el['functional_scope'] + puts "✓ Organisation #{org.name} has been updated" unless Rails.env.test? end end end diff --git a/app/models/referential.rb b/app/models/referential.rb index afadf5edd..8b8df3294 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -30,7 +30,7 @@ class Referential < ActiveRecord::Base validates_presence_of :line_referential belongs_to :created_from, class_name: 'Referential' - has_many :lines, through: :line_referential + has_many :associated_lines, through: :line_referential, source: :lines has_many :companies, through: :line_referential has_many :group_of_lines, through: :line_referential has_many :networks, through: :line_referential @@ -43,6 +43,10 @@ class Referential < ActiveRecord::Base has_many :stop_areas, through: :stop_area_referential belongs_to :workbench + def lines + workbench ? workbench.lines : associated_lines + end + def slug_excluded_values if ! slug.nil? if slug.start_with? "pg_" @@ -128,13 +132,6 @@ class Referential < ActiveRecord::Base }) end - def clone_association from - self.organisation = from.organisation - self.line_referential = from.line_referential - self.stop_area_referential = from.stop_area_referential - self.workbench = from.workbench - end - def self.available_srids [ [ "RGF 93 Lambert 93 (2154)", 2154 ], @@ -171,7 +168,8 @@ class Referential < ActiveRecord::Base projection_type || "" end - before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench + before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench, unless: :created_from + before_validation :clone_associations, :on => :create, if: :created_from before_create :create_schema after_create :create_referential_metadata, if: :workbench, unless: :created_from @@ -185,6 +183,13 @@ class Referential < ActiveRecord::Base self.referential_metadatas.create end + def clone_associations + self.organisation = created_from.organisation + self.line_referential = created_from.line_referential + self.stop_area_referential = created_from.stop_area_referential + self.workbench = created_from.workbench + end + def clone_referential_metadatas self.created_from.referential_metadatas.each do |meta| self.referential_metadatas << ReferentialMetadata.new_from(meta) diff --git a/app/models/stop_area_referential_sync_message.rb b/app/models/stop_area_referential_sync_message.rb index e965297da..d75c25ebb 100644 --- a/app/models/stop_area_referential_sync_message.rb +++ b/app/models/stop_area_referential_sync_message.rb @@ -1,6 +1,6 @@ class StopAreaReferentialSyncMessage < ActiveRecord::Base belongs_to :stop_area_referential_sync - enum criticity: [:info, :warn, :error] + enum criticity: [:info, :warning, :danger] validates :criticity, presence: true end diff --git a/app/models/user.rb b/app/models/user.rb index 8f0c32c54..5cfdf0605 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,16 +29,10 @@ class User < ActiveRecord::Base after_destroy :check_destroy_organisation def cas_extra_attributes=(extra_attributes) - extra = extra_attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} - self.name = extra[:full_name] - self.email = extra[:email] - - self.organisation = Organisation.find_or_create_by(code: extra[:organisation_code]).tap do |org| - org.name = extra[:organisation_name] - org.sso_attributes ||= {} - org.sso_attributes[:functional_scope] = extra[:functional_scope].delete('\\"') if extra[:functional_scope] - org.synced_at = Time.now - end + extra = extra_attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo} + self.name = extra[:full_name] + self.email = extra[:email] + self.organisation = Organisation.sync_update extra[:organisation_code], extra[:organisation_name], extra[:functional_scope] end def self.portail_api_request @@ -60,25 +54,14 @@ class User < ActiveRecord::Base def self.portail_sync self.portail_api_request.each do |el| - User.find_or_create_by(username: el['username']).tap do |user| - user.name = "#{el['firstname']} #{el['lastname']}" - user.email = el['email'] - user.locked_at = el['locked_at'] - - # Set organisation - user.organisation = Organisation.find_or_create_by(code: el['organization_code']).tap do |org| - org.name = el['organization_name'] - org.sso_attributes ||= {} - org.sso_attributes[:functional_scope] = el['functional_scope'].delete('\\"') if el['functional_scope'] - org.synced_at = Time.now - end - - if user.changed? - user.synced_at = Time.now - user.save - puts "✓ user #{user.username} has been updated" unless Rails.env.test? - end - end + user = User.find_or_initialize_by(username: el['username']) + user.name = "#{el['firstname']} #{el['lastname']}" + user.email = el['email'] + user.locked_at = el['locked_at'] + user.organisation = Organisation.sync_update el['organization_code'], el['organization_name'], el['functional_scope'] + user.synced_at = Time.now + user.save + puts "✓ user #{user.username} has been updated" unless Rails.env.test? end end diff --git a/app/models/workbench.rb b/app/models/workbench.rb index 3525fe55e..a83fea70d 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -3,6 +3,12 @@ class Workbench < ActiveRecord::Base belongs_to :line_referential belongs_to :stop_area_referential + has_many :lines, -> (workbench) { Stif::MyWorkbenchScopes.new(workbench).line_scope(self) }, through: :line_referential + has_many :networks, through: :line_referential + has_many :companies, through: :line_referential + has_many :group_of_lines, through: :line_referential + has_many :stop_areas, through: :stop_area_referential + validates :name, presence: true validates :organisation, presence: true diff --git a/app/views/api/kml/routes/show.kml.slim b/app/views/api/kml/routes/show.kml.slim index 3b08d81ce..51d2817c8 100644 --- a/app/views/api/kml/routes/show.kml.slim +++ b/app/views/api/kml/routes/show.kml.slim @@ -6,11 +6,11 @@ kml xmlns="http://www.opengis.net/kml/2.2" placemark id="#{@route.objectid}" name = h(@route.name) extendeddata - - [:direction_code, :wayback_code, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :published_name, :number, :direction, :wayback].each do |prop| + - [:direction, :wayback, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :published_name, :number, :direction_text, :wayback_text].each do |prop| data name="#{prop.to_s}" value = h(@route.send( prop)) data name="line_objectid" value = h(@route.line.objectid) - = @route.geometry_presenter.geometry.kml_representation.html_safe
\ No newline at end of file + = @route.geometry_presenter.geometry.kml_representation.html_safe diff --git a/app/views/footnotes/_footnote_fields.html.slim b/app/views/footnotes/_footnote_fields.html.slim index ab006cfa9..c1944ed2d 100644 --- a/app/views/footnotes/_footnote_fields.html.slim +++ b/app/views/footnotes/_footnote_fields.html.slim @@ -1,4 +1,4 @@ = f.inputs :class => 'nested-fields footnote' do = f.input :code, :wrapper_html => { class: 'col-md-3' } = f.input :label, :wrapper_html => { class: 'col-md-7' } - = link_to_remove_association t('actions.destroy'), f, class: 'col-md-2 remove'
\ No newline at end of file + = link_to_remove_association t('actions.destroy'), f, class: 'col-md-2 remove' diff --git a/app/views/line_referentials/show.html.slim b/app/views/line_referentials/show.html.slim index 406da8fee..95f097fc8 100644 --- a/app/views/line_referentials/show.html.slim +++ b/app/views/line_referentials/show.html.slim @@ -25,17 +25,19 @@ h3 Historique des synchronisations ul.list-group width="75%" - - @line_referential.line_referential_syncs.each do |sync| - - unless sync.line_referential_sync_messages.empty? - - sync.line_referential_sync_messages.last.tap do |log| - - if log.criticity = log.criticity - li.alert class="alert-#{log.criticity}" - strong = l(log.created_at, format: :short) + " : " - / [:processing_time] unit conversion - - data = log.message_attributs.symbolize_keys! - - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i) - - = t("line_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!) + - @line_referential.line_referential_syncs.each_with_index do |sync, i| + / Display only 10 msgs + - if i < 10 + - unless sync.line_referential_sync_messages.empty? + - sync.line_referential_sync_messages.last.tap do |log| + - if log.criticity = log.criticity + li.alert class="alert-#{log.criticity}" + strong = l(log.created_at, format: :short) + " : " + / [:processing_time] unit conversion + - data = log.message_attributs.symbolize_keys! + - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i) + + = t("line_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!) - content_for :sidebar do ul.actions diff --git a/app/views/lines/_form.html.slim b/app/views/lines/_form.html.slim index 113a5c46c..6c847b275 100644 --- a/app/views/lines/_form.html.slim +++ b/app/views/lines/_form.html.slim @@ -6,7 +6,7 @@ = form.input :published_name = form.input :registration_number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.line.registration_number")} = form.input :number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.line.number") } - = form.input :transport_mode, as: :select, :collection => Chouette::Line.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") } + = form.input :transport_mode, as: :select, :collection => @line.line_referential.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") } = form.input :color, as: :string = form.input :text_color = form.input :stable_id @@ -19,11 +19,11 @@ .footnotes_block h3 = t("footnotes.index.title") - + #footnotes = form.semantic_fields_for :footnotes do |f| = render "footnotes/footnote_fields", :f => f - + .add_footnote = link_to_add_association t("footnotes.actions.add_footnote"), form, :footnotes , :partial => "footnotes/footnote_fields", :"data-association-insertion-method" => "append", :"data-association-insertion-node" => "div#footnotes", class: 'add' @@ -32,7 +32,7 @@ = form.action :cancel, as: :link javascript: - $(function() { + $(function() { $("#line_group_of_line_tokens").tokenInput("#{name_filter_referential_group_of_lines_path(@line_referential, format: :json)}", { crossDomain: false, prePopulate: $('#group_of_line_tokens').data('pre'), @@ -42,4 +42,4 @@ javascript: noResultsText: "#{I18n.t('no_result_text')}", searchingText: "#{I18n.t('searching_term')}" }); - });
\ No newline at end of file + }); diff --git a/app/views/lines/show.html.slim b/app/views/lines/show.html.slim index cca0e395c..b314dee82 100644 --- a/app/views/lines/show.html.slim +++ b/app/views/lines/show.html.slim @@ -118,7 +118,8 @@ p.after_map -h3.routes = t('.itineraries') +h3.routes + = t('.itineraries') .routes.paginated_content / FIXME #825 diff --git a/app/views/referential_companies/_company.html.slim b/app/views/referential_companies/_company.html.slim index 06e13764e..e6090540d 100644 --- a/app/views/referential_companies/_company.html.slim +++ b/app/views/referential_companies/_company.html.slim @@ -2,10 +2,12 @@ .panel-heading .panel-title.clearfix span.pull-right - = link_to edit_referential_company_path(@referential, company), class: 'btn btn-default btn-sm' do - span.fa.fa-pencil - = link_to referential_company_path(@referential, company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do - span.fa.fa-trash-o + - if policy(company).update? + = link_to edit_referential_company_path(@referential, company), class: 'btn btn-default btn-sm' do + span.fa.fa-pencil + - if policy(company).destroy? + = link_to referential_company_path(@referential, company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do + span.fa.fa-trash-o h5 = link_to [@referential, company], class: 'preview', title: "#{Chouette::Company.model_name.human.capitalize} #{company.name}" do span.name @@ -13,4 +15,4 @@ .panel-body p = company.human_attribute_name('code') - = company.code
\ No newline at end of file + = company.code diff --git a/app/views/referential_companies/index.html.slim b/app/views/referential_companies/index.html.slim index b32f206ca..6af6d7fc8 100644 --- a/app/views/referential_companies/index.html.slim +++ b/app/views/referential_companies/index.html.slim @@ -19,6 +19,7 @@ - content_for :sidebar do ul.actions - li - = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add' - br
\ No newline at end of file + - if policy(Chouette::Company).create? + li + = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add' + br diff --git a/app/views/referential_companies/show.html.slim b/app/views/referential_companies/show.html.slim index a445dad61..a1a767bbd 100644 --- a/app/views/referential_companies/show.html.slim +++ b/app/views/referential_companies/show.html.slim @@ -44,12 +44,15 @@ - content_for :sidebar do ul.actions - li - = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add' - li - = link_to t('companies.actions.edit'), edit_referential_company_path(@referential, @company), class: 'edit' - li - = link_to t('companies.actions.destroy'), referential_company_path(@referential, @company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'remove' - br - - = creation_tag(@company)
\ No newline at end of file + - if policy(Chouette::Company).create? + li + = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add' + - if policy(@company).update? + li + = link_to t('companies.actions.edit'), edit_referential_company_path(@referential, @company), class: 'edit' + - if policy(@company).destroy? + li + = link_to t('companies.actions.destroy'), referential_company_path(@referential, @company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'remove' + br + + = creation_tag(@company) diff --git a/app/views/referential_lines/_form.html.slim b/app/views/referential_lines/_form.html.slim index f4e49b3a3..08a011017 100644 --- a/app/views/referential_lines/_form.html.slim +++ b/app/views/referential_lines/_form.html.slim @@ -6,7 +6,7 @@ = form.input :published_name = form.input :registration_number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.line.registration_number") } = form.input :number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.line.number") } - = form.input :transport_mode, as: :select, :collection => Chouette::Line.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") } + = form.input :transport_mode, as: :select, :collection => @line.line_referential.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") } = form.input :color, as: :string = form.input :text_color = form.input :stable_id @@ -19,7 +19,7 @@ .footnotes_block h3 = t("footnotes.index.title") - + #footnotes = form.semantic_fields_for :footnotes do |f| = render "footnotes/footnote_fields", f: f @@ -42,4 +42,4 @@ javascript: noResultsText: "#{I18n.t('no_result_text')}", searchingText: "#{I18n.t('searching_term')}" }); - });
\ No newline at end of file + }); diff --git a/app/views/referential_lines/_line.html.slim b/app/views/referential_lines/_line.html.slim index 0dffb50aa..1c8b8eaa8 100644 --- a/app/views/referential_lines/_line.html.slim +++ b/app/views/referential_lines/_line.html.slim @@ -3,7 +3,7 @@ ul.ce-LineBlock-header-list li = check_box_tag "ids[]", line.id, false, class: "multiple_selection", style: "display: none;" - + - if line.number && line.number.length <= 3 span.label.label-default.line_number style="#{number_style(line)}" = line.number @@ -13,11 +13,11 @@ h5.ce-LineBlock-header-title = truncate(line.name, length: 24) li - - if edit + - if edit && policy(Chouette::Line).update? = link_to edit_referential_line_path(@referential, line), class: 'btn btn-default btn-sm' do span.fa.fa-pencil - - if delete + - if delete && policy(Chouette::Line).destroy? = link_to referential_line_path(@referential, line), method: :delete, data: { confirm: t('lines.actions.destroy_confirm') }, class: 'btn btn-danger btn-sm' do span.fa.fa-trash-o @@ -46,4 +46,4 @@ = line.human_attribute_name('group_of_line') = link_to_if( line.group_of_lines.first, line.group_of_lines.first.name, referential_group_of_line_path(@referential, line.group_of_lines.first), :title => "#{line.human_attribute_name('group_of_line')} #{line.group_of_lines.first.name}") - else - = t('lines.form.several_group_of_lines', :count => line.group_of_lines.count)
\ No newline at end of file + = t('lines.form.several_group_of_lines', :count => line.group_of_lines.count) diff --git a/app/views/referential_lines/_reflines_routes.html.slim b/app/views/referential_lines/_reflines_routes.html.slim new file mode 100644 index 000000000..43cc908b4 --- /dev/null +++ b/app/views/referential_lines/_reflines_routes.html.slim @@ -0,0 +1,30 @@ +table.table.table-bordered.table-hover + thead + tr + th.text-center = @routes.human_attribute_name(:name) + th.text-center = @routes.human_attribute_name(:published_name) + th.text-center = @routes.human_attribute_name(:wayback) + th.text-center = @routes.human_attribute_name(:opposite_route) + th.text-center = "Actions" + + - @routes.each do |route| + tr + td = truncate(route.name, length: 20) + td = route.published_name + td = route.wayback_text + td + - if route.opposite_route + = route.opposite_route.name + - else + = "Aucune séquence d'arrêts associée en sens opposé" + + td.text-center + .btn.btn-group.btn-group-sm + = link_to [@referential, @line, route], class: 'btn btn-default preview', title: "#{Chouette::Route.model_name.human.capitalize} #{route.name}" do + span.fa.fa-eye + + = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do + span.fa.fa-pencil + + = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do + span.fa.fa-trash-o diff --git a/app/views/referential_lines/index.html.slim b/app/views/referential_lines/index.html.slim index 4922cde85..5647bde0c 100644 --- a/app/views/referential_lines/index.html.slim +++ b/app/views/referential_lines/index.html.slim @@ -24,25 +24,27 @@ - content_for :sidebar do ul.actions - li - = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add' + - if policy(Chouette::Line).create? + li + = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add' - #multiple_selection_menu - h4> = t(".multi_selection") + - if policy(Chouette::Line).destroy? + #multiple_selection_menu + h4> = t(".multi_selection") - .disabled - a.enable href="#" - = t(".multi_selection_enable") + .disabled + a.enable href="#" + = t(".multi_selection_enable") - .enabled style="display: none;" - a.disable href="#" - = t(".multi_selection_disable") + .enabled style="display: none;" + a.disable href="#" + = t(".multi_selection_disable") - ul.actions - = link_to t(".delete_selected"), referential_lines_path(@referential), "data-multiple-method" => "delete", :class => "remove", "confirmation-text" => t("lines.actions.destroy_selection_confirm") + ul.actions + = link_to t(".delete_selected"), referential_lines_path(@referential), "data-multiple-method" => "delete", :class => "remove", "confirmation-text" => t("lines.actions.destroy_selection_confirm") a.select_all href="#" = t(".select_all") = " | " a.deselect_all href="#" - = t(".deselect_all")
\ No newline at end of file + = t(".deselect_all") diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index ae8314a14..4c439d08a 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -54,51 +54,51 @@ label = "#{@line.human_attribute_name('url')} : " = @line.url - p - label = "#{@line.human_attribute_name('mobility_restricted_suitability')} : " - - - if @line.mobility_restricted_suitability.nil? - = @line.human_attribute_name("unspecified_mrs") - - elsif @line.mobility_restricted_suitability? - = @line.human_attribute_name("accessible") - - else - = @line.human_attribute_name("not_accessible") - - br - = "#{@line.human_attribute_name('number_of_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', true).count}" - br - = "#{@line.human_attribute_name('number_of_non_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', false).count}" - br - = "#{@line.human_attribute_name('number_of_null_mrs_vj')} : " - = @line.vehicle_journeys.count - (@line.vehicle_journeys.where("mobility_restricted_suitability = ?", true).count + @line.vehicle_journeys.where("mobility_restricted_suitability = ?", false).count) - - p - label = "#{@line.human_attribute_name('flexible_service')} : " - - - if @line.flexible_service.nil? - = @line.human_attribute_name("unspecified_fs") - - elsif @line.flexible_service? - = @line.human_attribute_name("on_demaond_fs") - - else - = @line.human_attribute_name("regular_fs") - - br - = "#{@line.human_attribute_name('number_of_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', true).count}" - br - = "#{@line.human_attribute_name('number_of_non_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', false).count}" - br - = @line.human_attribute_name("number_of_null_fs_vj") - - - if @line.flexible_service.nil? - = "(#{@line.human_attribute_name('default_fs_msg')})" - - = ": #{@line.vehicle_journeys.count - (@line.vehicle_journeys.where('flexible_service = ?', true).count + @line.vehicle_journeys.where('flexible_service = ?', false).count)}" - - p - label = "#{@line.human_attribute_name('footnotes')} : " - ul - - @line.footnotes.each do |footnote| - li = "#{footnote.code} : #{footnote.label}" + / p + / label = "#{@line.human_attribute_name('mobility_restricted_suitability')} : " + / + / - if @line.mobility_restricted_suitability.nil? + / = @line.human_attribute_name("unspecified_mrs") + / - elsif @line.mobility_restricted_suitability? + / = @line.human_attribute_name("accessible") + / - else + / = @line.human_attribute_name("not_accessible") + / + / br + / = "#{@line.human_attribute_name('number_of_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', true).count}" + / br + / = "#{@line.human_attribute_name('number_of_non_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', false).count}" + / br + / = "#{@line.human_attribute_name('number_of_null_mrs_vj')} : " + / = @line.vehicle_journeys.count - (@line.vehicle_journeys.where("mobility_restricted_suitability = ?", true).count + @line.vehicle_journeys.where("mobility_restricted_suitability = ?", false).count) + / + / p + / label = "#{@line.human_attribute_name('flexible_service')} : " + / + / - if @line.flexible_service.nil? + / = @line.human_attribute_name("unspecified_fs") + / - elsif @line.flexible_service? + / = @line.human_attribute_name("on_demaond_fs") + / - else + / = @line.human_attribute_name("regular_fs") + / + / br + / = "#{@line.human_attribute_name('number_of_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', true).count}" + / br + / = "#{@line.human_attribute_name('number_of_non_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', false).count}" + / br + / = @line.human_attribute_name("number_of_null_fs_vj") + / + / - if @line.flexible_service.nil? + / = "(#{@line.human_attribute_name('default_fs_msg')})" + / + / = ": #{@line.vehicle_journeys.count - (@line.vehicle_journeys.where('flexible_service = ?', true).count + @line.vehicle_journeys.where('flexible_service = ?', false).count)}" + / + / p + / label = "#{@line.human_attribute_name('footnotes')} : " + / ul + / - @line.footnotes.each do |footnote| + / li = "#{footnote.code} : #{footnote.label}" p label = "#{@line.human_attribute_name('comment')} : " @@ -109,27 +109,33 @@ #flexible_service.col-md-6 p.after_map -h3.routes = t('.itineraries') +h3.routes + = t('.itineraries') .routes.paginated_content - = paginated_content @routes, "routes/route" + / = paginated_content @routes, "routes/route" + = render 'reflines_routes' - if @line.group_of_lines.any? h3.line_group_of_lines = t('.group_of_lines') .group_of_lines.paginated_content - = paginated_content @group_of_lines, "group_of_lines/group_of_line", :delete => false + = paginated_content @group_of_lines, "referential_group_of_lines/group_of_line", :delete => false - content_for :sidebar do ul.actions - li - = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add' - li - = link_to t('lines.actions.edit'), edit_referential_line_path(@referential, @line), class: 'edit' - li - = link_to t('lines.actions.destroy'), referential_line_path(@referential, @line), method: :delete, :data => {:confirm => t('lines.actions.destroy_confirm')}, class: 'remove' + - if policy(Chouette::Line).create? + li + = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add' + - if policy(@line).update? + li + = link_to t('lines.actions.edit'), edit_referential_line_path(@referential, @line), class: 'edit' + - if policy(@line).destroy? + li + = link_to t('lines.actions.destroy'), referential_line_path(@referential, @line), method: :delete, :data => {:confirm => t('lines.actions.destroy_confirm')}, class: 'remove' - if !@line.hub_restricted? || (@line.hub_restricted? && @line.routes.size < 2) - li + / FIXME #825 + li = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add' - = creation_tag(@line)
\ No newline at end of file + = creation_tag(@line) diff --git a/app/views/referential_networks/_network.html.slim b/app/views/referential_networks/_network.html.slim index dc1aa6b5c..f7c7b66eb 100644 --- a/app/views/referential_networks/_network.html.slim +++ b/app/views/referential_networks/_network.html.slim @@ -2,13 +2,14 @@ .panel-heading .panel-title.clearfix span.pull-right - = link_to edit_referential_network_path(@referential, network), class: 'btn btn-default btn-sm' do - span.fa.fa-pencil - - = link_to referential_network_path(@referential, network), method: :delete, :data => { :confirm => t('networks.actions.destroy_confirm') }, class: 'btn btn-danger btn-sm' do - span.fa.fa-trash-o + - if policy(network).update? + = link_to edit_referential_network_path(@referential, network), class: 'btn btn-default btn-sm' do + span.fa.fa-pencil + - if policy(network).destroy? + = link_to referential_network_path(@referential, network), method: :delete, :data => { :confirm => t('networks.actions.destroy_confirm') }, class: 'btn btn-danger btn-sm' do + span.fa.fa-trash-o h5 = link_to [@referential, network], class: 'preview', title: "#{Chouette::Network.model_name.human.capitalize} #{network.name}" do span.name - = truncate(network.name, :length => 20)
\ No newline at end of file + = truncate(network.name, :length => 20) diff --git a/app/views/referential_networks/index.html.slim b/app/views/referential_networks/index.html.slim index f3ead931e..e3e9f2a07 100644 --- a/app/views/referential_networks/index.html.slim +++ b/app/views/referential_networks/index.html.slim @@ -19,5 +19,6 @@ - content_for :sidebar do ul.actions li + - if policy(Chouette::Network).create? = link_to t('networks.actions.new'), new_referential_network_path(@referential), class: 'add' - br
\ No newline at end of file + br diff --git a/app/views/referential_networks/show.html.slim b/app/views/referential_networks/show.html.slim index 936f6a4a8..d579d311b 100644 --- a/app/views/referential_networks/show.html.slim +++ b/app/views/referential_networks/show.html.slim @@ -36,12 +36,15 @@ - content_for :sidebar do ul.actions - li - = link_to t('networks.actions.new'), new_referential_network_path(@referential), class: 'add' - li - = link_to t('networks.actions.edit'), edit_referential_network_path(@referential, @network), class: 'edit' - li - = link_to t('networks.actions.destroy'), referential_network_path(@referential, @network), method: :delete, data: { :confirm => t('networks.actions.destroy_confirm')}, class: 'remove' - br - - = creation_tag(@network)
\ No newline at end of file + - if policy(Chouette::Network).create? + li + = link_to t('networks.actions.new'), new_referential_network_path(@referential), class: 'add' + - if policy(@network).update? + li + = link_to t('networks.actions.edit'), edit_referential_network_path(@referential, @network), class: 'edit' + - if policy(@network).destroy? + li + = link_to t('networks.actions.destroy'), referential_network_path(@referential, @network), method: :delete, data: { :confirm => t('networks.actions.destroy_confirm')}, class: 'remove' + br + + = creation_tag(@network) diff --git a/app/views/referential_stop_areas/_genealogical.html.slim b/app/views/referential_stop_areas/_genealogical.html.slim index a44884c92..162c24d9b 100644 --- a/app/views/referential_stop_areas/_genealogical.html.slim +++ b/app/views/referential_stop_areas/_genealogical.html.slim @@ -5,7 +5,7 @@ h3 = genealogical_title = link_to([@referential, @stop_area.parent], :title => t("area_types.label.#{@stop_area.parent.stop_area_type}") + "#{@stop_area.parent.name}") do = image_tag "map/" + @stop_area.parent.stop_area_type + ".png" = @stop_area.parent.name - + .link = image_tag "icons/link.png" @@ -18,7 +18,7 @@ h3 = genealogical_title .link = image_tag "icons/link.png" - else - .no_parent = + .no_parent .target = image_tag "map/" + @stop_area.stop_area_type + ".png" @@ -51,4 +51,4 @@ h3 = genealogical_title span = route.line.number = link_to([@referential, route.line , route]) do - span = route.name
\ No newline at end of file + span = route.name diff --git a/app/views/referential_stop_areas/_stop_area.html.slim b/app/views/referential_stop_areas/_stop_area.html.slim index f94bd319e..bb9ed7ce3 100644 --- a/app/views/referential_stop_areas/_stop_area.html.slim +++ b/app/views/referential_stop_areas/_stop_area.html.slim @@ -2,11 +2,13 @@ .panel-heading .panel-title.clearfix span.pull-right - = link_to edit_referential_stop_area_path(@referential, stop_area), class: 'btn btn-default btn-sm' do - span.fa.fa-pencil + - if policy(stop_area).update? + = link_to edit_referential_stop_area_path(@referential, stop_area), class: 'btn btn-default btn-sm' do + span.fa.fa-pencil - = link_to referential_stop_area_path(@referential, stop_area), method: :delete, :data => {:confirm => t('stop_areas.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do - span.fa.fa-trash-o + - if policy(stop_area).destroy? + = link_to referential_stop_area_path(@referential, stop_area), method: :delete, :data => {:confirm => t('stop_areas.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do + span.fa.fa-trash-o h5 = link_to([@referential, stop_area], class: "preview", :title => t("area_types.label.#{stop_area.stop_area_type}") + " #{stop_area.name}") do @@ -34,11 +36,11 @@ - else - stop_area.routing_lines.each do |line| span.label.label-default.line = line.number - + - else = "#{t('.lines')} : " - if stop_area.lines.blank? = t(".no_object") - else - stop_area.lines.each do |line| - span.label.label-default.line = line.number || truncate( line.name, length: 4 )
\ No newline at end of file + span.label.label-default.line = line.number || truncate( line.name, length: 4 ) diff --git a/app/views/referential_stop_areas/index.html.slim b/app/views/referential_stop_areas/index.html.slim index 85bd15d20..1b634b09c 100644 --- a/app/views/referential_stop_areas/index.html.slim +++ b/app/views/referential_stop_areas/index.html.slim @@ -26,7 +26,8 @@ - content_for :sidebar do ul.actions + - if policy(Chouette::StopArea).create? + li + = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add' li - = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add' - li - / = link_to t('stop_areas.actions.default_geometry'), default_geometry_referential_stop_areas_path(@referential), :method => :put, :class => "calculator"
\ No newline at end of file + / = link_to t('stop_areas.actions.default_geometry'), default_geometry_referential_stop_areas_path(@referential), :method => :put, :class => "calculator" diff --git a/app/views/referential_stop_areas/show.html.slim b/app/views/referential_stop_areas/show.html.slim index 76414edf0..2278c4812 100644 --- a/app/views/referential_stop_areas/show.html.slim +++ b/app/views/referential_stop_areas/show.html.slim @@ -109,7 +109,7 @@ p.after_map .genealogical.clearfix - = render "stop_areas/genealogical" + = render "referential_stop_areas/genealogical" - if manage_access_points div @@ -122,22 +122,25 @@ p.after_map tr td ul.actions - li - = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add' - li - = link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), class: 'edit' - li - = link_to t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), method: :delete, data: { :confirm => t('stop_areas.actions.destroy_confirm') }, class: 'remove' + - if policy(Chouette::StopArea).new? + li + = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add' + - if policy(@stop_area).update? + li + = link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), class: 'edit' + - if policy(@stop_area).destroy? + li + = link_to t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), method: :delete, data: { :confirm => t('stop_areas.actions.destroy_confirm') }, class: 'remove' - if manage_itl - tr - td - h4 = t('.itl_managment') - ul.actions - li - = link_to t('stop_areas.actions.add_routing_lines'), add_routing_lines_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_lines' - li - = link_to t('stop_areas.actions.add_routing_stops'), add_routing_stops_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_stops' + / tr + / td + / h4 = t('.itl_managment') + / ul.actions + / li + / = link_to t('stop_areas.actions.add_routing_lines'), add_routing_lines_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_lines' + / li + / = link_to t('stop_areas.actions.add_routing_stops'), add_routing_stops_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_stops' - else tr @@ -145,17 +148,17 @@ p.after_map h4 = t('.stop_managment') ul.actions li - = link_to t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), class: 'parent' + / = link_to t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), class: 'parent' - if @stop_area.parent == nil li - = link_to t('stop_areas.actions.clone_as_parent'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'parent'), class: 'clone' + / = link_to t('stop_areas.actions.clone_as_parent'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'parent'), class: 'clone' - if manage_children li - = link_to t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), class: 'children' + / = link_to t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), class: 'children' li - = link_to t('stop_areas.actions.clone_as_child'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'child'), class: 'clone' + / = link_to t('stop_areas.actions.clone_as_child'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'child'), class: 'clone' - if manage_access_points tr @@ -163,9 +166,9 @@ p.after_map h4 = t(".access_managment") ul.actions li - = link_to t('access_points.actions.new'), new_referential_stop_area_access_point_path(@referential,@stop_area), class: 'add' + / = link_to t('access_points.actions.new'), new_referential_stop_area_access_point_path(@referential,@stop_area), class: 'add' li - = link_to t('stop_areas.actions.manage_access_links'), access_links_referential_stop_area_path(@referential,@stop_area), class: 'access_link' + / = link_to t('stop_areas.actions.manage_access_links'), access_links_referential_stop_area_path(@referential,@stop_area), class: 'access_link' br diff --git a/app/views/referentials/_counts.html.slim b/app/views/referentials/_counts.html.slim index fc3ad251e..9754ebc99 100644 --- a/app/views/referentials/_counts.html.slim +++ b/app/views/referentials/_counts.html.slim @@ -67,4 +67,4 @@ li.list-group-item span.badge = @referential.access_points.size = image_tag "map/access_in_out.png" - = Referential.human_attribute_name("access_points")
\ No newline at end of file + = Referential.human_attribute_name("access_points") diff --git a/app/views/referentials/index.html.slim b/app/views/referentials/index.html.slim index e37f157de..c03943ac7 100644 --- a/app/views/referentials/index.html.slim +++ b/app/views/referentials/index.html.slim @@ -14,12 +14,3 @@ / FIXME #823 - if false li = link_to t('referentials.actions.new'), new_referential_path, class: 'add' - - ul - / FIXME #820 - / Don't blame me. See #820 - li = link_to 'Données Reflex', stop_area_referential_path(1) - - / FIXME #824 - / Don't blame me. See #824 - li = link_to 'Données CodifLigne', line_referential_path(1) diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim index d5fed0344..1fc8f108f 100644 --- a/app/views/referentials/show.html.slim +++ b/app/views/referentials/show.html.slim @@ -44,7 +44,7 @@ h2 - if @referential.api_keys.present? h3.api_keys = t('.api_keys') - + .api_keys.paginated_content = paginated_content(@referential.api_keys, "api_keys/api_key") @@ -66,8 +66,9 @@ h2 li = link_to t('referentials.actions.destroy'), referential_path(@referential), method: :delete, data: {:confirm => t('referentials.actions.destroy_confirm')}, class: "remove" li = link_to t('api_keys.actions.new'), new_referential_api_key_path(@referential), class: 'add' + li = link_to t('referentials.actions.clone'), new_referential_path(from: @referential.id), class: 'add' br h4 = t('.clean_up') - == render 'clean'
\ No newline at end of file + == render 'clean' diff --git a/app/views/referentials/show.js.slim b/app/views/referentials/show.js.slim index f1d01ce6c..5e47bf935 100644 --- a/app/views/referentials/show.js.slim +++ b/app/views/referentials/show.js.slim @@ -3,7 +3,6 @@ | update_infos = function(json) { | var info, update_info; | info = $('#referential_' + json.referential_id); -| console.log(info) | update_info = function(key, value) { | if (key.match(/_count$/)) { | return $(info.find('.' + key)[0]).text(value); @@ -16,5 +15,5 @@ | }; | _results = []; | _results.push(update_referential_details()); -| return _results; -| });
\ No newline at end of file +| return _results; +| }); diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim index 329862955..3dd813fc2 100644 --- a/app/views/routes/_form.html.slim +++ b/app/views/routes/_form.html.slim @@ -1,91 +1,53 @@ -= semantic_form_for [@referential, @line, @route] do |form| - = form.inputs do - = form.input :name - = form.input :published_name - = form.input :number - = form.input :comment - = form.input :opposite_route, as: :select, :collection => @line.routes.select { |r| r.id != @route.id } - = form.input :direction_code, as: :select, :collection => Chouette::Route.directions, :include_blank => false, :member_label => Proc.new { |mode| t("directions.label.#{mode}") } - = form.input :wayback_code, as: :select, :collection => Chouette::Route.waybacks, :include_blank => false, :member_label => Proc.new { |mode| t("waybacks.label.#{mode}") } - = form.input :objectid, :required => !@route.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.route.objectid")} - - #stop_points - = form.semantic_fields_for :stop_points, :include_id => false do |p| - == render "stop_point_fields", f: p - - .links - = link_to_add_association t("routes.actions.add_stop_point"), form, :stop_points, class: 'add_stop_point add' - br - = link_to t('routes.actions.new_stop_point'), new_referential_stop_area_path(@referential), { class: 'add', target: '_blank' } - - = form.actions do - = form.action :submit, as: :button - = form.action :cancel, as: :link - -javascript: - $(document).ready(function() { - var stop_point_ids = []; - - var order_position = function() { - $('#stop_points input[type="hidden"][id$="position"]').each(function(index) { - $(this).val(index); - }); - }; - - var write_stop_point_ids = function(){ - $('#stop_points input[type="hidden"][class~="stop_point_id"]').each(function(index,element) { - // soit le parent a la classe added_stop_point - if ( $(element).hasClass("added_stop_point") ){ - $(this).attr("value", ""); - } else { - $(this).attr("value", stop_point_ids.shift()); - } - }); - } - - var empty_stop_point_ids = function() { - stop_point_ids = $.map($('#stop_points input[type="hidden"][class="stop_point_id"]'), function(element, index) { - return $(element).val(); - }); - // console.log( "before-remove"); - // console.log( stop_point_ids); - }; - - $('#stop_points').sortable({ - axis: 'y', - dropOnEmpty: false, - handle: '.handle', - cursor: 'crosshair', - items: '.stop_point', - opacity: 0.4, - scroll: true, - start: function( event, ui ) { - empty_stop_point_ids(); - }, - update: function( event, ui ) { - write_stop_point_ids(); - order_position(); - } - }); - - $('#stop_points').bind("cocoon:after-insert", function(event, insertedItem) { - var new_stop_count = $('div.nested-fields.stop_point').size(); - var cocoonId = insertedItem.find("input.new_stop_point").attr("id").match( /route_stop_points_attributes_(\d+)_stop_area_id/)[1]; - insertedItem.find('input').each( function(index,e){ - var old = $(e).attr("name"); - if (old!=undefined) { - $(e).attr("name", old.replace( cocoonId, new_stop_count - 1)); - } - }); - - //console.log( "cocoonId="+cocoonId+", new_stop_count="+new_stop_count); - order_position(); - }); - - $('#stop_points').on("cocoon:before-remove", empty_stop_point_ids); - - $('#stop_points').on("cocoon:after-remove", function() { - write_stop_point_ids(); - order_position(); - }); - });
\ No newline at end of file += simple_form_for [@referential, @line, @route] do |f| + .row + .col-lg-4.col-md-4.col-sm-4.col-xs-4 + = f.input :name + .col-lg-4.col-md-4.col-sm-4.col-xs-4 + = f.input :published_name + .col-lg-4.col-md-4.col-sm-4.col-xs-4 + = f.input :number + + .row + .col-lg-6.col-md-6.col-sm-5.col-xs-5 + = f.input :comment + .col-lg-6.col-md-6.col-sm-7.col-xs-7 + = f.input :opposite_route, collection: @line.routes.select { |r| r.id != @route.id } + + .row + .col-lg-4.col-md-4.col-sm-4.col-xs-4 + = f.input :direction, include_blank: false + .col-lg-4.col-md-4.col-sm-4.col-xs-4 + = f.input :wayback, include_blank: false + .col-lg-4.col-md-4.col-sm-4.col-xs-4 + = f.input :objectid, required: !@route.new_record?, input_html: { title: t("formtastic.titles#{format_restriction_for_locales(@referential)}.route.objectid") } + + .row style="margin-top:20px" + .col-lg-12.col-md-12.col-sm-12.col-xs-12 + #stop_points + / div.clearfix style="margin-bottom:5px" + / label style="margin:0" Arrêts + / .btn.btn-primary.btn-xs.pull-right data-event="add_stop_point" + / span.fa.fa-plus + / = " #{t('routes.actions.add_stop_point')}" + / + / = link_to_add_association f, :stop_points, class: 'btn btn-primary btn-xs pull-right' do + / span.fa.fa-plus + / = " #{t('routes.actions.add_stop_point')}" + / THIS IS BROKEN + / = link_to t('routes.actions.new_stop_point'), new_referential_stop_area_path(@referential), target: '_blank' + / + / .list-group + / = f.simple_fields_for :stop_points do |point| + / = render 'stop_point_fields', f: point + + .row + .col-lg-12.col-md-12.col-sm-12.col-xs-12.text-right + = link_to 'Annuler', :back, class: 'btn btn-link' + = f.button :submit, class: 'btn btn-danger' + +// Get JSON data for route stop points += javascript_tag do + | window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}" + +/ StopPoints Reactux component += javascript_include_tag 'es6_browserified/stop_points.js' diff --git a/app/views/routes/_route.html.slim b/app/views/routes/_route.html.slim index fd740fa9b..251c92000 100644 --- a/app/views/routes/_route.html.slim +++ b/app/views/routes/_route.html.slim @@ -1,19 +1,19 @@ #index_item.panel.panel-default.route .panel-heading .panel-title.clearfix - span.pull-right - = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default btn-sm' do + .btn-group.btn-group-sm.pull-right + = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do span.fa.fa-pencil - = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do + = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do span.fa.fa-trash-o h5 = link_to [@referential, @line, route], class: 'preview', title: "#{Chouette::Route.model_name.human.capitalize} #{route.name}" do span.name - - if route.wayback_code + - if route.wayback = fonticon_wayback(route.wayback) - + = truncate(route.name, length: 20) .panel-body @@ -38,6 +38,6 @@ p - if !route.direction.blank? - = "#{route.human_attribute_name('direction_code')} : #{t('directions.label.'+route.direction_code)}" + => "#{route.human_attribute_name('direction')} : #{route.direction_text}" - else - br
\ No newline at end of file + br diff --git a/app/views/routes/_stop_point_fields.html.slim b/app/views/routes/_stop_point_fields.html.slim index 814e882c2..3b51e5e0d 100644 --- a/app/views/routes/_stop_point_fields.html.slim +++ b/app/views/routes/_stop_point_fields.html.slim @@ -1,16 +1,23 @@ -.nested-fields.stop_point.row - = f.inputs do - .col-md-1.resize - = link_to_remove_association "<i class='fa fa-trash-o'></i>".html_safe, f - span.handle alt="#{t('stop_points.index.move')}" title="#{t('stop_points.index.move')}" > - i.fa.fa-arrows - - .col-md-11 - - if f.object.stop_area.nil? || f.object.new_record? - = f.input :id, as: :hidden, :input_html => { :class => "stop_point_id added_stop_point", :value => "" } - = f.input :position, as: :hidden, :input_html => { :class => "position" } +.list-group-item + div style="display:inline-block;vertical-align:middle;width:75%;" + - if f.object.stop_area.nil? || f.object.new_record? + / = f.input :stop_area_id, label: false = f.input :stop_area_id, :label => false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "new_stop_point stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render } - - else - = f.input :id, as: :hidden, :input_html => { class: 'stop_point_id' } - = f.input :position, as: :hidden, :input_html => { class: 'position' } - = f.input :stop_area_id, label: false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render }
\ No newline at end of file + + - else + = "#{@route.stop_areas.find(f.object.stop_area_id).name} " + em.small + = "#{@route.stop_areas.find(f.object.stop_area_id).zip_code} #{@route.stop_areas.find(f.object.stop_area_id).city_name}" + + div.text-right style="display:inline-block;vertical-align:middle;width:25%;" + .btn-group.btn-group-sm style="padding:0;" + .btn.btn-default + span.fa.fa-times + .btn.btn-primary + span.fa.fa-arrow-up + .btn.btn-primary + span.fa.fa-arrow-down + .btn.btn-danger + span.fa.fa-trash + / = link_to_remove_association f, class: 'btn btn-danger', data: {confirm: 'Are you sure?'} do + / span.fa.fa-trash diff --git a/app/views/routes/_test.html.slim b/app/views/routes/_test.html.slim new file mode 100644 index 000000000..deb525d32 --- /dev/null +++ b/app/views/routes/_test.html.slim @@ -0,0 +1,36 @@ +.list-group-item + = f.inputs do + - if f.object.stop_area.nil? || f.object.new_record? + div style="display:inline-block;vertical-align:middle;width:75%;" + span + span.text-danger = "[#{@route.stop_areas.find(f.object.stop_area_id).position.inspect}] " + = @route.stop_areas.find(f.object.stop_area_id).name + + / = f.input :stop_area_id, :label => false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "new_stop_point stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render } + + = f.input :stop_area_id, :label => false, as: :search_stop_area + + = f.input :id, as: :hidden, :input_html => { :class => "stop_point_id added_stop_point", :value => "" } + = f.input :position, as: :hidden, :input_html => { :class => "position" } + + - else + div style="display:inline-block;vertical-align:middle;width:75%;" + span + span.text-danger = "[#{@route.stop_areas.find(f.object.stop_area_id).position.inspect}] " + = @route.stop_areas.find(f.object.stop_area_id).name + + / = f.input :stop_area_id, label: false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render } + + = f.input :id, as: :hidden, :input_html => { class: 'stop_point_id' } + = f.input :position, as: :hidden, :input_html => { class: 'position' } + + div.text-right style="display:inline-block;;vertical-align:middle;width:25%;" + .btn-group.btn-group-sm style="padding:0;" + .btn.btn-default + span.fa.fa-times + .btn.btn-primary + span.fa.fa-arrow-up + .btn.btn-primary + span.fa.fa-arrow-down + = link_to_remove_association f, class: 'btn btn-danger' do + span.fa.fa-trash diff --git a/app/views/routes/edit.html.slim b/app/views/routes/edit.html.slim index 7e2c1f982..a0431dc32 100644 --- a/app/views/routes/edit.html.slim +++ b/app/views/routes/edit.html.slim @@ -1,3 +1,5 @@ = title_tag t('routes.edit.title', route: @route.name ) -== render 'form'
\ No newline at end of file +.row + .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2 + == render 'form' diff --git a/app/views/routes/new.html.slim b/app/views/routes/new.html.slim index e91ebf362..51410a2e5 100644 --- a/app/views/routes/new.html.slim +++ b/app/views/routes/new.html.slim @@ -1,3 +1,5 @@ = title_tag t('routes.new.title') -== render 'form'
\ No newline at end of file +.row + .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2 + == render 'form' diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim index a4e1aa90f..968fc5795 100644 --- a/app/views/routes/show.html.slim +++ b/app/views/routes/show.html.slim @@ -6,66 +6,72 @@ .summary p label = "#{@route.human_attribute_name(:name)} : " - = @route.name + = " #{@route.name}" p label = "#{@route.human_attribute_name(:published_name)} : " - = @route.published_name + = " #{@route.published_name}" + + / p + / label = "#{@route.human_attribute_name(:number)} : " + / = " #{@route.number}" + / + / p + / label = "#{@route.human_attribute_name(:comment)} : " + / = " #{@route.comment}" + / + / p + / label = "#{@route.human_attribute_name(:direction)} : " + / - if @route.direction + / = " #{@route.direction_text}" + / - else + / = " #{t('.undefined')}" p - label = "#{@route.human_attribute_name(:number)} : " - = @route.number - - p - label = "#{@route.human_attribute_name(:comment)} : " - = @route.comment - - p - label = "#{@route.human_attribute_name(:direction_code)} : " - - if @route.direction_code - = t("directions.label.#{@route.direction_code}").capitalize - - else - = t(".undefined") - - p - label = "#{@route.human_attribute_name(:wayback_code)} : " - - if @route.wayback_code - = t("waybacks.label.#{@route.wayback_code}").capitalize + label = "#{@route.human_attribute_name(:wayback)} : " + - if @route.wayback + = " #{@route.wayback_text}" - else - = t(".undefined") + = " #{t('.undefined')}" p label = "#{@route.human_attribute_name(:opposite_route)} : " - if @route.opposite_route = link_to @route.opposite_route.name, [@referential, @line, @route.opposite_route] - else - = t(".no_opposite_route") + = " #{t('.no_opposite_route')}" p.after_map -#accordion.panel-group - .panel.panel-default - .panel-heading - h4.panel-title - a data-toggle="collapse" data-parent="#accordion" href="#stop_points" - = t('.stop_points') - - #stop_points.panel-collapse.collapse - .panel-body - .stop_points.paginated_content - = paginated_content(@route.stop_points, "stop_points/stop_point") - -#accordion.panel-group - .panel.panel-default - .panel-heading - h4.panel-title - a data-toggle="collapse" data-parent="#accordion" href="#journey_patterns" - = t('.journey_patterns') - - #journey_patterns.panel-collapse.collapse - .panel-body - .journey_patterns.paginated_content - = paginated_content( @route.journey_patterns, "journey_patterns/journey_pattern") +#stop_points.panel.panel-default + .panel-heading + h4.panel-title + strong = t('.stop_points') + + .list-group + - @route.stop_points.each do |point| + - if point.stop_area.zip_code && point.stop_area.city_name + - linktxt = "#{point.stop_area.name}, #{point.stop_area.zip_code} #{point.stop_area.city_name}" + - else + - linktxt = "#{point.stop_area.name}" + + = link_to [@referential, point.stop_area], { style: 'display: table;width: 100%;', class: 'list-group-item', title: "Voir l'arrêt '#{linktxt}'" } do + div style='display: table-cell;vertical-align: middle;' + div style='display: inline-block;width: 10%;vertical-align: middle;text-align: right;' + span.label.label-default style='margin-right: 10px;' + = "#{point.stop_area.id}" + div style='display: inline-block;width: 90%;vertical-align: middle;' + = linktxt + + +/ .panel.panel-default +/ .panel-heading +/ h4.panel-title +/ strong = t('.journey_patterns') +/ +/ .panel-body +/ .journey_patterns.paginated_content +/ = paginated_content( @route.journey_patterns, "journey_patterns/journey_pattern") - content_for :sidebar do ul.actions @@ -76,10 +82,10 @@ p.after_map ul.actions - if @route.stop_points.size >= 2 li = link_to t('journey_patterns.actions.new'), new_referential_line_route_journey_pattern_path(@referential, @line, @route), class: 'add' - + - if @route.stop_points.present? li = link_to t('routes.actions.edit_boarding_alighting'), edit_boarding_alighting_referential_line_route_path(@referential, @line, @route), class: 'edit' - + - if @route.journey_patterns.size > 0 li = link_to t('vehicle_journeys.actions.index'), [@referential, @line, @route, :vehicle_journeys], class: 'clock' @@ -87,4 +93,4 @@ p.after_map li = link_to t('vehicle_journey_imports.new.title'), new_referential_line_route_vehicle_journey_import_path( @referential, @line, @route ), class: 'import' li = link_to t('vehicle_journey_exports.new.title'), referential_line_route_vehicle_journey_exports_path(@referential, @line, @route, format: :zip), class: 'export' - = creation_tag(@route)
\ No newline at end of file + = creation_tag(@route) diff --git a/app/views/rule_parameter_sets/_form.html.slim b/app/views/rule_parameter_sets/_form.html.slim index 74ad9ae3b..de3368a1b 100644 --- a/app/views/rule_parameter_sets/_form.html.slim +++ b/app/views/rule_parameter_sets/_form.html.slim @@ -25,7 +25,7 @@ thead tr th = t("transport_modes.name") - + - RuleParameterSet.mode_attribute_prefixes.each do |prefix| - if prefix == "allowed_transport" - hidden = (@rule_parameter_set.check_allowed_transport_modes == "1") ? "" : 'display:none;' @@ -35,6 +35,7 @@ th = RuleParameterSet.human_attribute_name(prefix) tbody + / To be removed, see #1936 - Chouette::Line.transport_modes.map(&:to_s).each do |mode| tr == render partial: "mode_fields", :locals => { f: form, mode: mode } @@ -69,4 +70,4 @@ javascript: $( "#rule_parameter_set_check_allowed_transport_modes").change( function() { $(".allowed").toggle(); }); - });
\ No newline at end of file + }); diff --git a/app/views/rule_parameter_sets/show.html.slim b/app/views/rule_parameter_sets/show.html.slim index 2d54f4572..72a8fa99c 100644 --- a/app/views/rule_parameter_sets/show.html.slim +++ b/app/views/rule_parameter_sets/show.html.slim @@ -5,10 +5,10 @@ p label = "#{RuleParameterSet.human_attribute_name('stop_areas_area')} : " = @rule_parameter_set.stop_areas_area - + .attributes_group span.title = t(".min_distance") - + .columns .two_columns label = "#{t('.inter_stop_area_distance_min')} : " @@ -20,7 +20,7 @@ .attributes_group span.title = t(".max_distance") - + .columns .two_columns label = "#{t('.parent_stop_area_distance_max')} : " @@ -91,23 +91,23 @@ table.table.table-striped.table-condensed tr th = t("transport_modes.name") - + - RuleParameterSet.mode_attribute_prefixes.each do |prefix| - unless prefix == "allowed_transport" th = RuleParameterSet.human_attribute_name(prefix) - + / To be removed, see #1936 - Chouette::Line.transport_modes.map(&:to_s).each do |mode| - if @rule_parameter_set.allowed(mode) tr td = t("transport_modes.label.#{mode}") - + - RuleParameterSet.mode_attribute_prefixes.each do |prefix| - unless prefix == "allowed_transport" td = @rule_parameter_set.send "#{prefix}_mode_#{mode}" .rule_parameter_by_object label = t("rule_parameter_sets.labels.columns_restrictions") - + table.table.table-bordered.table-condensed - RuleParameterSet.validable_object_names.each do |object_name| - if @rule_parameter_set.selected(object_name) @@ -119,7 +119,7 @@ th = RuleParameterSet.human_attribute_name("string_type") th = RuleParameterSet.human_attribute_name("min_size") th = RuleParameterSet.human_attribute_name("max_size") - + tbody - RuleParameterSet.validable_columns[object_name].each do |col| - if @rule_parameter_set.selected_column(object_name,col) @@ -140,4 +140,4 @@ li = link_to t('rule_parameter_sets.actions.edit'), edit_organisation_rule_parameter_set_path( @rule_parameter_set), class: 'edit' - if current_organisation.rule_parameter_sets.size > 1 - li = link_to t('rule_parameter_sets.actions.destroy'), organisation_rule_parameter_set_path( @rule_parameter_set), method: :delete, data: { confirm: t('rule_parameter_sets.actions.destroy_confirm') }, class: 'remove'
\ No newline at end of file + li = link_to t('rule_parameter_sets.actions.destroy'), organisation_rule_parameter_set_path( @rule_parameter_set), method: :delete, data: { confirm: t('rule_parameter_sets.actions.destroy_confirm') }, class: 'remove' diff --git a/app/views/shared/_header.html.slim b/app/views/shared/_header.html.slim index 27b0139c2..73e705e35 100644 --- a/app/views/shared/_header.html.slim +++ b/app/views/shared/_header.html.slim @@ -7,7 +7,7 @@ nav.navbar.navbar-default.navbar-fixed-top role="navigation" span.icon-bar span.icon-bar span.icon-bar - span.icon-bar.version = APP_VERSION + / span.icon-bar.version = APP_VERSION = link_to referentials_path, class: 'navbar-brand' do / = image_tag("logo_chouette.png") @@ -85,12 +85,12 @@ nav.navbar.navbar-default.navbar-fixed-top role="navigation" = link_to referential_route_sections_path(@referential) do span.badge.pull-right = @referential.route_sections.size = Referential.human_attribute_name("route_sections") - + li = link_to referential_timebands_path(@referential) do span.badge.pull-right = @referential.timebands.size = Referential.human_attribute_name("timebands") - + li = link_to Referential.human_attribute_name("imports"), referential_imports_path(@referential) li @@ -128,4 +128,4 @@ nav.navbar.navbar-default.navbar-fixed-top role="navigation" li = link_to t('layouts.user.sign_out'), destroy_user_session_path, method: :delete li.divider li - = tab_link_to Organisation.model_name.human, organisation_path
\ No newline at end of file + = tab_link_to Organisation.model_name.human, organisation_path diff --git a/app/views/stop_area_referentials/show.html.slim b/app/views/stop_area_referentials/show.html.slim index 9cceed5e5..907cdb168 100644 --- a/app/views/stop_area_referentials/show.html.slim +++ b/app/views/stop_area_referentials/show.html.slim @@ -13,17 +13,19 @@ h3 Historique des synchronisations ul.list-group width="75%" - - @stop_area_referential.stop_area_referential_syncs.each do |sync| - - unless sync.stop_area_referential_sync_messages.empty? - - sync.stop_area_referential_sync_messages.last.tap do |log| - - if log.criticity = log.criticity - li.alert class="alert-#{log.criticity}" - strong = l(log.created_at, format: :short) + " : " - / [:processing_time] unit conversion - - data = log.message_attributs.symbolize_keys! - - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i) + - @stop_area_referential.stop_area_referential_syncs.each_with_index do |sync, i| + / Display only 10 msgs + - if i < 10 + - unless sync.stop_area_referential_sync_messages.empty? + - sync.stop_area_referential_sync_messages.last.tap do |log| + - if log.criticity = log.criticity + li.alert class="alert-#{log.criticity}" + strong = l(log.created_at, format: :short) + " : " + / [:processing_time] unit conversion + - data = log.message_attributs.symbolize_keys! + - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i) - = t("stop_area_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!) + = t("stop_area_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!) - content_for :sidebar do ul.actions diff --git a/app/views/vehicle_journeys/_form.html.slim b/app/views/vehicle_journeys/_form.html.slim index bc26e1ac5..61d6b0e06 100644 --- a/app/views/vehicle_journeys/_form.html.slim +++ b/app/views/vehicle_journeys/_form.html.slim @@ -7,7 +7,7 @@ = form.input :published_journey_name = form.input :published_journey_identifier = form.input :comment - = form.input :transport_mode_name, as: :select, :collection => Chouette::Line.transport_modes, :include_blank => true, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") } + = form.input :transport_mode_name, as: :select, :collection => @line.line_referential.transport_modes, :include_blank => true, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") } = form.input :mobility_restricted_suitability, as: :select, :collection => [[vehicle_journey.human_attribute_name("accessible"), true], [vehicle_journey.human_attribute_name("not_accessible"), false]], :include_blank => true = form.input :flexible_service, as: :select, :collection => [[vehicle_journey.human_attribute_name("on_demand_fs"), true], [vehicle_journey.human_attribute_name("regular_fs"), false]], :include_blank => true = form.input :status_value @@ -23,4 +23,4 @@ = form.action :submit, as: :button, label: t(".submit_#{vehicle_journey.journey_category}#{'_edit' unless form.object.new_record?}"), button_html: { class: 'btn btn-primary' } = form.action :cancel, as: :link -== render 'form_footer', vehicle_journey: vehicle_journey
\ No newline at end of file +== render 'form_footer', vehicle_journey: vehicle_journey diff --git a/app/workers/clean_up_worker.rb b/app/workers/clean_up_worker.rb new file mode 100644 index 000000000..f758b900b --- /dev/null +++ b/app/workers/clean_up_worker.rb @@ -0,0 +1,16 @@ +class CleanUpWorker + include Sidekiq::Worker + + def perform(id) + cleaner = CleanUp.find id + cleaner.run! + begin + cleaner.referential.switch + result = cleaner.clean + cleaner.successful! + rescue Exception => e + Rails.logger.error "CleanUpWorker : #{e}" + cleaner.failed! + end + end +end |
