diff options
| author | Xinhui | 2017-01-09 12:12:02 +0100 |
|---|---|---|
| committer | Xinhui | 2017-01-09 12:12:02 +0100 |
| commit | cced737f5e806df59bd0008ae0c82aee712a7ce9 (patch) | |
| tree | 2d42c8e5b59a6031f3100fac098ed2ff3e679cc9 | |
| parent | 93ad8ee168b86ecc4ed6e918063c12030b96ac09 (diff) | |
| parent | 953fb3a48c43f5801bbc35dd02a2db26b21479b1 (diff) | |
| download | chouette-core-cced737f5e806df59bd0008ae0c82aee712a7ce9.tar.bz2 | |
Merge branch 'master' into staging
239 files changed, 4826 insertions, 1221 deletions
@@ -1,4 +1,4 @@ -# coding: utf-8 +# coding: iso-8859-1 source 'http://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' @@ -65,7 +65,7 @@ gem 'codifligne', git: 'git@github.com:AF83/stif-codifline-api.git' gem 'reflex', git: 'git@github.com:AF83/stif-reflex-api.git' # Authentication -gem 'devise', '~> 3.4.0' +gem 'devise', '~> 3.5.4' gem 'devise_cas_authenticatable' gem 'devise-encryptable' gem 'devise_invitable' @@ -87,7 +87,7 @@ gem 'calendar_helper', '0.2.5' gem 'cocoon' gem 'slim-rails', '~> 3.1' gem 'formtastic', '2.3.1' -gem 'RedCloth' +gem 'RedCloth', '~> 4.3.0' gem 'simple_form', '~> 3.1.0' gem 'font-awesome-sass', '~> 4.2.0' gem 'will_paginate-bootstrap', '~> 1.0.1' @@ -141,6 +141,8 @@ group :development do # MetaRequest is incompatible with rgeo-activerecord # gem 'meta_request' gem 'quiet_assets', '~> 1.0' + gem 'license_finder' + gem 'bundler-audit' platforms :ruby_20, :ruby_21, :ruby_22 do gem 'better_errors' @@ -190,8 +192,6 @@ gem 'i18n-tasks' # Rails Assets source 'http://rails-assets.org' do - gem 'rails-assets-morrisjs', '~> 0.5.1' - gem 'rails-assets-raphael', '~> 2.1.3' gem 'rails-assets-footable', '~> 2.0.3' # Use twitter bootstrap resources diff --git a/Gemfile.lock b/Gemfile.lock index 4fb4e2532..4e07a585a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -32,8 +32,7 @@ GEM remote: http://rubygems.org/ remote: http://rails-assets.org/ specs: - RedCloth (4.2.9) - RedCloth (4.2.9-java) + RedCloth (4.3.2) SyslogLogger (2.0) aasm (4.5.2) actionmailer (4.1.10) @@ -83,8 +82,8 @@ GEM astrolabe (1.3.0) parser (>= 2.2.0.pre.3, < 3.0) awesome_print (1.6.1) - bcrypt (3.1.10) - bcrypt (3.1.10-java) + bcrypt (3.1.11) + bcrypt (3.1.11-java) better_errors (2.1.1) coderay (>= 1.0.0) erubis (>= 2.6.6) @@ -95,6 +94,9 @@ GEM browserify-rails (1.1.0) railties (>= 4.0.0, < 5.0) builder (3.2.2) + bundler-audit (0.5.0) + bundler (~> 1.2) + thor (~> 0.18) calendar_helper (0.2.5) open4 capistrano (2.13.5) @@ -155,7 +157,7 @@ GEM debug_inspector (0.0.2) deep_cloneable (2.0.2) activerecord (>= 3.1.0, < 5.0.0) - devise (3.4.1) + devise (3.5.10) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) @@ -248,6 +250,8 @@ GEM hike (1.2.3) hitimes (1.2.2) hitimes (1.2.2-java) + httparty (0.14.0) + multi_xml (>= 0.5.2) i18n (0.7.0) i18n-tasks (0.8.6) activesupport @@ -280,6 +284,12 @@ GEM letter_opener (1.4.1) launchy (~> 2.2) libv8 (3.16.14.11) + license_finder (2.1.2) + bundler + httparty + rubyzip + thor + xml-simple listen (2.8.6) celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) @@ -295,6 +305,7 @@ GEM minitest (5.9.1) multi_json (1.11.2) multi_test (0.1.2) + multi_xml (0.5.5) multipart-post (2.0.0) nenv (0.2.0) net-scp (1.2.1) @@ -372,14 +383,8 @@ GEM rails-assets-jquery (>= 1.5) rails-assets-jquery-ui (1.11.4) rails-assets-jquery (>= 1.6) - rails-assets-mocha (1.17.1) rails-assets-modernizr (2.0.6) rails-assets-moment (2.10.3) - rails-assets-morrisjs (0.5.1) - rails-assets-jquery (>= 2.1.0) - rails-assets-mocha (~> 1.17.1) - rails-assets-raphael (>= 2.0) - rails-assets-raphael (2.1.4) rails-assets-respond (1.4.2) rails-assets-tagmanager (3.0.1) rails-assets-jquery (>= 1.0.0) @@ -528,7 +533,7 @@ GEM therubyracer (0.12.2) libv8 (~> 3.16.14.0) ref - thor (0.19.1) + thor (0.19.4) thread (0.2.2) thread_safe (0.3.5) thread_safe (0.3.5-java) @@ -550,7 +555,7 @@ GEM uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) - warden (1.2.3) + warden (1.2.6) rack (>= 1.0) webmock (2.1.0) addressable (>= 2.3.6) @@ -564,6 +569,7 @@ GEM will_paginate (3.0.7) will_paginate-bootstrap (1.0.1) will_paginate (>= 3.0.3) + xml-simple (1.1.5) xpath (2.0.0) nokogiri (~> 1.3) @@ -572,7 +578,7 @@ PLATFORMS ruby DEPENDENCIES - RedCloth + RedCloth (~> 4.3.0) SyslogLogger aasm active_attr @@ -586,6 +592,7 @@ DEPENDENCIES binding_of_caller breadcrumbs_on_rails browserify-rails + bundler-audit calendar_helper (= 0.2.5) capistrano (= 2.13.5) capistrano-ext @@ -598,7 +605,7 @@ DEPENDENCIES daemons database_cleaner deep_cloneable (~> 2.0.0) - devise (~> 3.4.0) + devise (~> 3.5.4) devise-async devise-encryptable devise-i18n @@ -629,6 +636,7 @@ DEPENDENCIES language_engine (= 0.0.6) launchy letter_opener + license_finder map_layers (= 0.0.4) mimemagic newrelic_rpm @@ -647,8 +655,6 @@ DEPENDENCIES rails-assets-jquery-tokeninput (~> 1.7.0)! rails-assets-jquery-ui (~> 1.11.4)! rails-assets-modernizr (~> 2.0.6)! - rails-assets-morrisjs (~> 0.5.1)! - rails-assets-raphael (~> 2.1.3)! rails-assets-respond! rails-assets-tagmanager (~> 3.0.1.0)! rails-assets-typeahead.js (~> 0.10.5)! diff --git a/app/assets/images/map/commercial_stop_point.png b/app/assets/images/map/lda.png Binary files differindex 2c87dc31a..2c87dc31a 100644 --- a/app/assets/images/map/commercial_stop_point.png +++ b/app/assets/images/map/lda.png diff --git a/app/assets/images/map/quay.png b/app/assets/images/map/zdep.png Binary files differindex a2bd8e954..a2bd8e954 100644 --- a/app/assets/images/map/quay.png +++ b/app/assets/images/map/zdep.png diff --git a/app/assets/images/map/zder.png b/app/assets/images/map/zder.png Binary files differnew file mode 100644 index 000000000..a2bd8e954 --- /dev/null +++ b/app/assets/images/map/zder.png diff --git a/app/assets/images/map/stop_place.png b/app/assets/images/map/zdlp.png Binary files differindex b5058573e..b5058573e 100644 --- a/app/assets/images/map/stop_place.png +++ b/app/assets/images/map/zdlp.png diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b0e100684..835a716e4 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -4,13 +4,12 @@ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // the compiled file. // +//= require turbolinks //= require jquery //= require jquery_ujs //= require jquery-ui //= require modernizr //= require cocoon -//= require raphael -//= require morrisjs //= require bootstrap-sass-official //= require select2-full //= require select2_locale_fr @@ -32,7 +31,6 @@ //= require_directory ./vehicle_journey_frequencies //= require_directory ./import_tasks //= require_directory ./compliance_check_tasks -//= require_directory ./compliance_checks //= require_directory ./export_tasks //= require_directory ./exports //= require_directory ./lines diff --git a/app/assets/javascripts/compliance_checks/report.coffee b/app/assets/javascripts/compliance_checks/report.coffee deleted file mode 100644 index 2bff8742e..000000000 --- a/app/assets/javascripts/compliance_checks/report.coffee +++ /dev/null @@ -1,62 +0,0 @@ -$(".compliance_checks.report, .imports.compliance_check, #sidebar.compliance_checks_sidebar").ready -> - refreshInterval = $(".report").data("refresh-interval") - if refreshInterval > 0 - reloadPage = () -> window.location.reload() - setInterval(reloadPage,refreshInterval * 1000) - - footableFilter = (parent, el) -> - $(parent).footable().bind 'footable_filtering', (e) -> - selected = $("select#{el} option:selected").val() - if selected and selected.length > 0 - e.filter += if e.filter and e.filter.length > 0 then ' ' + selected else selected - e.clear = !e.filter - return - $("select#{el}").change (e) -> - e.preventDefault() - $(parent).trigger 'footable_filter', filter: $("select#{el} option:selected").val() - return - - insertSeverityDonut = (type) -> - triggerFilter = (type,state) -> - $("select.filter-status option[value='status-#{state}']").prop('selected', true) - $('.table').trigger 'footable_filter', filter: "#{state}_#{type}" - momo = Morris.Donut({ - element: type, - data: [ - { label: $(".table").data('title-nok'), value: $("tr.nok_#{type}").size() }, - { label: $(".table").data('title-uncheck'), value: $("tr.uncheck_#{type}").size() }, - { label: $(".table").data('title-ok'), value: $("tr.ok_#{type}").size() } - ], - colors: [ "#e22b1b", "#898e7f", "#8fc861" ] - }).on('click', update = (i, row) -> - switch i - when 0 then triggerFilter(type,'nok') - when 1 then triggerFilter(type,'uncheck') - when 2 then triggerFilter(type,'ok') - ) - $('select.filter-status').change (e)-> - switch $('select.filter-status option:selected').val() - when 'status-nok' then momo.select(0) - when 'status-uncheck' then momo.select(1) - when 'status-ok' then momo.select(2) - $("##{type}").hide() - - insertSeverityDonut('error') - insertSeverityDonut('warning') - - $(".notice").popover({ container: "body", html: false, trigger: "focus", placement: "bottom" }) - # Hide and show error details - $(".title_error").each -> - $( this ).click -> - $(this).next(".details_error").toggle() - $(this).children("i").toggleClass("fa-plus-square fa-minus-square") - - footableFilter('table', '.filter-status') - footableFilter('table', '.filter-severity') - - $('select.filter-severity').change (e)-> - $('.graph').hide() - if $('select.filter-severity option:selected').val() == 'severity-warning' - $('#warning').show() - if $('select.filter-severity option:selected').val() == 'severity-error' - $('#error').show() diff --git a/app/assets/javascripts/es6_browserified/actions/index.js b/app/assets/javascripts/es6_browserified/itineraries/actions/index.js index 7d225f2f6..7d225f2f6 100644 --- a/app/assets/javascripts/es6_browserified/actions/index.js +++ b/app/assets/javascripts/es6_browserified/itineraries/actions/index.js diff --git a/app/assets/javascripts/es6_browserified/components/App.js b/app/assets/javascripts/es6_browserified/itineraries/components/App.js index 7488b0b39..7488b0b39 100644 --- a/app/assets/javascripts/es6_browserified/components/App.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/App.js diff --git a/app/assets/javascripts/es6_browserified/components/BSelect2.js b/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js index 0bd53a083..0bf3ebf38 100644 --- a/app/assets/javascripts/es6_browserified/components/BSelect2.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js @@ -92,7 +92,8 @@ class BSelect2 extends React.Component{ delay: '500', data: function(params) { return { - q: params.term + q: params.term, + target_type: 'zdep' }; }, processResults: function(data, params) { diff --git a/app/assets/javascripts/es6_browserified/components/Todo.js b/app/assets/javascripts/es6_browserified/itineraries/components/Todo.js index f2932ab1d..f2932ab1d 100644 --- a/app/assets/javascripts/es6_browserified/components/Todo.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/Todo.js diff --git a/app/assets/javascripts/es6_browserified/components/TodoList.js b/app/assets/javascripts/es6_browserified/itineraries/components/TodoList.js index 3ea2c90e1..3ea2c90e1 100644 --- a/app/assets/javascripts/es6_browserified/components/TodoList.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/TodoList.js diff --git a/app/assets/javascripts/es6_browserified/containers/AddTodo.js b/app/assets/javascripts/es6_browserified/itineraries/containers/AddTodo.js index d0128f16d..d0128f16d 100644 --- a/app/assets/javascripts/es6_browserified/containers/AddTodo.js +++ b/app/assets/javascripts/es6_browserified/itineraries/containers/AddTodo.js diff --git a/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js b/app/assets/javascripts/es6_browserified/itineraries/containers/VisibleTodoList.js index 464d6e482..464d6e482 100644 --- a/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js +++ b/app/assets/javascripts/es6_browserified/itineraries/containers/VisibleTodoList.js diff --git a/app/assets/javascripts/es6_browserified/form_helper.js b/app/assets/javascripts/es6_browserified/itineraries/form_helper.js index d48718841..d48718841 100644 --- a/app/assets/javascripts/es6_browserified/form_helper.js +++ b/app/assets/javascripts/es6_browserified/itineraries/form_helper.js diff --git a/app/assets/javascripts/es6_browserified/reducers/index.js b/app/assets/javascripts/es6_browserified/itineraries/reducers/index.js index 381b32d8b..381b32d8b 100644 --- a/app/assets/javascripts/es6_browserified/reducers/index.js +++ b/app/assets/javascripts/es6_browserified/itineraries/reducers/index.js diff --git a/app/assets/javascripts/es6_browserified/reducers/todos.js b/app/assets/javascripts/es6_browserified/itineraries/reducers/todos.js index 215a3e2c2..215a3e2c2 100644 --- a/app/assets/javascripts/es6_browserified/reducers/todos.js +++ b/app/assets/javascripts/es6_browserified/itineraries/reducers/todos.js diff --git a/app/assets/javascripts/es6_browserified/stop_points.js b/app/assets/javascripts/es6_browserified/itineraries/stop_points.js index d5f53fb4f..d5f53fb4f 100644 --- a/app/assets/javascripts/es6_browserified/stop_points.js +++ b/app/assets/javascripts/es6_browserified/itineraries/stop_points.js diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js new file mode 100644 index 000000000..f3235f963 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js @@ -0,0 +1,133 @@ +const actions = { + receiveJourneyPatterns : (json) => ({ + type: "RECEIVE_JOURNEY_PATTERNS", + json + }), + loadFirstPage: (dispatch) => ({ + type: 'LOAD_FIRST_PAGE', + dispatch + }), + goToPreviousPage : (dispatch, currentPage) => ({ + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + currentPage, + nextPage : false + }), + goToNextPage : (dispatch, currentPage) => ({ + type: 'GO_TO_NEXT_PAGE', + dispatch, + currentPage, + nextPage : true + }), + updateCheckboxValue : (e, index) => ({ + type : 'UPDATE_CHECKBOX_VALUE', + id : e.currentTarget.id, + index + }), + openConfirmModal : (accept, cancel) => ({ + type : 'OPEN_CONFIRM_MODAL', + accept, + cancel + }), + openEditModal : (index, journeyPattern) => ({ + type : 'EDIT_JOURNEYPATTERN_MODAL', + index, + journeyPattern + }), + openCreateModal : () => ({ + type : 'CREATE_JOURNEYPATTERN_MODAL' + }), + deleteJourneyPattern : (index) => ({ + type : 'DELETE_JOURNEYPATTERN', + index, + }), + closeModal : () => ({ + type : 'CLOSE_MODAL' + }), + saveModal : (index, data) => ({ + type: 'SAVE_MODAL', + data, + index + }), + addJourneyPattern : (data) => ({ + type: 'ADD_JOURNEYPATTERN', + data, + }), + savePage : (dispatch, currentPage) => ({ + type: 'SAVE_PAGE', + dispatch + }), + submitJourneyPattern : (dispatch, state) => { + let urlJSON = window.location.pathname + ".json" + let req = new Request(urlJSON, { + credentials: 'same-origin', + method: 'PATCH', + contentType: 'application/json; charset=utf-8', + Accept: 'application/json', + body: JSON.stringify(state), + headers: { + 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') + } + }) + fetch(req) + .then(response => response.json()) + .then((json) => { + console.log('request for submit') + // dispatch(actions.receiveJourneyPatterns(journeyPatterns)) + }) + }, + fetchJourneyPatterns : (dispatch, currentPage, nextPage) => { + if(currentPage == undefined){ + currentPage = 1 + } + let journeyPatterns = [] + let page + switch (nextPage) { + case true: + page = currentPage + 1 + break + case false: + if(currentPage > 1){ + page = currentPage - 1 + } + break + default: + page = currentPage + break + } + let str = ".json" + if(page > 1){ + str = '.json?page=' + page.toString() + } + let urlJSON = window.location.pathname + str + let req = new Request(urlJSON, { + credentials: 'same-origin', + }) + fetch(req) + .then(response => response.json()) + .then((json) => { + let val + for (val of json){ + for (let stop_point of val.route_short_description.stop_points){ + stop_point.checked = false + val.stop_area_short_descriptions.map((element) => { + if(element.stop_area_short_description.id === stop_point.id){ + stop_point.checked = true + } + }) + } + journeyPatterns.push({ + name: val.name, + object_id: val.object_id, + published_name: val.published_name, + registration_number: val.registration_number, + stop_points: val.route_short_description.stop_points, + deletable: false + }) + } + dispatch(actions.receiveJourneyPatterns(journeyPatterns)) + }) + } +} + +module.exports = actions diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/App.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/App.js new file mode 100644 index 000000000..5d84f28fd --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/App.js @@ -0,0 +1,22 @@ +var React = require('react') +var AddJourneyPattern = require('../containers/AddJourneyPattern') +var Navigate = require('../containers/Navigate') +var Modal = require('../containers/Modal') +var ConfirmModal = require('../containers/ConfirmModal') +var SaveJourneyPattern = require('../containers/SaveJourneyPattern') +var JourneyPatternList = require('../containers/JourneyPatternList') + +const App = () => ( + <div> + <div className='clearfix' style={{ marginBottom: 10 }}> + <Navigate /> + <AddJourneyPattern /> + </div> + <JourneyPatternList /> + <SaveJourneyPattern /> + <ConfirmModal /> + <Modal/> + </div> +) + +module.exports = App diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/ConfirmModal.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/ConfirmModal.js new file mode 100644 index 000000000..42653f823 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/ConfirmModal.js @@ -0,0 +1,40 @@ +var React = require('react') +var Component = require('react').Component +var PropTypes = require('react').PropTypes + +const ConfirmModal = ({modal, onModal}) => ( + <div className={ 'modal fade ' + ((modal.type == 'confirm') ? 'in' : '') } id='ConfirmModal'> + <div className='modal-dialog'> + <div className='modal-content'> + <div className='modal-body'> + <p> Voulez-vous sauver vos modifications avant de blabblabla? </p> + </div> + <div className='modal-footer'> + <button + className='btn btn-default' + data-dismiss='modal' + type='button' + onClick= {() => {onModal(modal.confirmModal.cancel)}} + > + Annuler + </button> + <button + className='btn btn-danger' + data-dismiss='modal' + type='button' + onClick = {() => {onModal(modal.confirmModal.accept)}} + > + Valider + </button> + </div> + </div> + </div> + </div> +) + +ConfirmModal.propTypes = { + modal: PropTypes.object.isRequired, + onModal: PropTypes.func.isRequired +} + +module.exports = ConfirmModal diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js new file mode 100644 index 000000000..2c75dd808 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js @@ -0,0 +1,105 @@ +var React = require('react') +var Component = require('react').Component +var PropTypes = require('react').PropTypes + +class CreateModal extends Component { + constructor(props) { + super(props) + } + handleSubmit(e) { + e.preventDefault() + this.props.onAddJourneyPattern(this.refs) + } + + render() { + return ( + <div className='pull-right'> + <button + type='button' + className='btn btn-primary btn-sm' + data-toggle='modal' + data-target='#NewJourneyPatternModal' + onClick={this.props.onOpenCreateModal} + > + <span className='fa fa-plus'></span> Ajouter une mission + </button> + + <div className={ 'modal fade ' + ((this.props.modal.type == 'create') ? 'in' : '') } id='NewJourneyPatternModal'> + <div className='modal-dialog'> + <div className='modal-content'> + <div className='modal-header clearfix'> + <h4>Ajouter une mission</h4> + </div> + + <div className='modal-body'> + {(this.props.modal.type == 'create') && ( + <form> + <div className='form-group'> + <label>Nom</label> + <input + type='text' + ref='name' + className='form-control' + /> + </div> + <div className='row'> + <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'> + <div className='form-group'> + <label>Nom public</label> + <input + type='text' + ref='published_name' + className='form-control' + /> + </div> + </div> + <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'> + <div className='form-group'> + <label>N° d'enregistrement</label> + <input + type='text' + ref='registration_number' + className='form-control' + /> + </div> + </div> + </div> + </form> + )} + </div> + + <div className='modal-footer'> + <button + className='btn btn-default' + data-dismiss='modal' + type='button' + onClick={this.props.onModalClose} + > + Annuler + </button> + <button + className='btn btn-danger' + data-dismiss='modal' + type='button' + onClick={this.handleSubmit.bind(this)} + > + Valider + </button> + </div> + </div> + </div> + </div> + </div> + ) + } +} + +CreateModal.propTypes = { + index: PropTypes.number, + modal: PropTypes.object, + onOpenCreateModal: PropTypes.func.isRequired, + onModalClose: PropTypes.func.isRequired, + onAddJourneyPattern: PropTypes.func.isRequired +} + +module.exports = CreateModal diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/EditModal.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/EditModal.js new file mode 100644 index 000000000..d3dcd333d --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/EditModal.js @@ -0,0 +1,130 @@ +var React = require('react') +var Component = require('react').Component +var PropTypes = require('react').PropTypes + +class EditModal extends Component { + constructor(props) { + super(props) + } + handleSubmit(e) { + e.preventDefault() + this.props.saveModal(this.props.modal.modalProps.index, this.refs) + } + + render() { + return ( + <div className={ 'modal fade ' + ((this.props.modal.type == 'edit') ? 'in' : '') } id='JourneyPatternModal'> + <div className='modal-dialog'> + <div className='modal-content'> + <div className='modal-header clearfix'> + <h4 className='pull-left'> + Modifier la mission + {(this.props.modal.type == 'edit') && ( + <em> "{this.props.modal.modalProps.journeyPattern.name}"</em> + )} + </h4> + <div className='btn-group btn-group-sm pull-right'> + <button + type='button' + className='btn btn-primary dropdown-toggle' + data-toggle='dropdown' + > + <span className='fa fa-bars'></span> + <span className='caret'></span> + </button> + + <ul className='dropdown-menu'> + <li><a href='#'>Horaires des courses</a></li> + <li> + <a + href='#' + data-dismiss='modal' + onClick={(e) => { + e.preventDefault() + this.props.onDeleteJourneyPattern(this.props.modal.modalProps.index)} + } + > + Supprimer la mission + </a> + </li> + </ul> + </div> + </div> + <div className='modal-body'> + {(this.props.modal.type == 'edit') && ( + <form> + <div className='form-group'> + <label>Nom</label> + <input + type='text' + ref='name' + className='form-control' + id={this.props.modal.modalProps.index} + defaultValue={this.props.modal.modalProps.journeyPattern.name} + /> + </div> + + <div className='row'> + <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'> + <div className='form-group'> + <label>Nom public</label> + <input + type='text' + ref='published_name' + className='form-control' + id={this.props.modal.modalProps.index} + defaultValue={this.props.modal.modalProps.journeyPattern.published_name} + /> + </div> + </div> + <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'> + <div className='form-group'> + <label>N° d'enregistrement</label> + <input + type='text' + ref='registration_number' + className='form-control' + id={this.props.modal.modalProps.index} + defaultValue={this.props.modal.modalProps.journeyPattern.registration_number} + /> + </div> + </div> + </div> + + </form> + )} + </div> + <div className='modal-footer'> + <button + className='btn btn-default' + data-dismiss='modal' + type='button' + onClick={this.props.onModalClose} + > + Annuler + </button> + <button + className='btn btn-danger' + data-dismiss='modal' + type='button' + onClick={this.handleSubmit.bind(this)} + > + Valider + </button> + </div> + </div> + </div> + </div> + ) + } +} + +EditModal.propTypes = { + index: PropTypes.number, + modal: PropTypes.object, + onModalClose: PropTypes.func.isRequired, + saveModal: PropTypes.func.isRequired, + onDeleteJourneyPattern: PropTypes.func.isRequired +} + +module.exports = EditModal diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js new file mode 100644 index 000000000..78e2e6d9c --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js @@ -0,0 +1,55 @@ +var React = require('react') +var PropTypes = require('react').PropTypes + +const JourneyPattern = (props) => { + return ( + <div className={'list-group-item ' + (props.value.deletable ? 'disabled' : '') + (props.value.object_id ? '' : 'to_record')}> + <div style={{display: 'inline-block', verticalAlign: 'top', width: '40%'}}> + <p className='small'><strong>Index: </strong>{props.index}</p> + <p className='small'><strong>Name: </strong>{props.value.name}</p> + </div> + + <div style={{display: 'inline-block', verticalAlign: 'top', width: '40%'}}> + <p className='small'><strong>ObjectID: </strong>{props.value.object_id}</p> + <p className='small'><strong>Published name: </strong>{props.value.published_name}</p> + </div> + + <div className='clearfix' style={{display: 'inline-block', verticalAlign: 'top', width: '20%'}}> + <button className={(props.value.deletable ? 'disabled' : '') + ' btn btn-xs btn-danger pull-right'} onClick={props.onOpenEditModal} data-toggle='modal' data-target='#JourneyPatternModal'> + <span className='fa fa-pencil'></span> + </button> + </div> + + <p className='small'><strong>Stop points: </strong></p> + <ul className='list-group'> + {props.value.stop_points.map((stopPoint, i) => + <li + key={ i } + className='list-group-item clearfix' + > + <span className='label label-default' style={{marginRight: 5}}>{stopPoint.id}</span> + <span>{stopPoint.name}</span> + <span className='pull-right'> + <input + onChange = {(e) => props.onCheckboxChange(e)} + type='checkbox' + id={stopPoint.id} + checked={stopPoint.checked} + disabled={props.value.deletable ? 'disabled' : ''} + ></input> + </span> + </li> + )} + </ul> + </div> + ) +} + +JourneyPattern.propTypes = { + value: PropTypes.object, + index: PropTypes.number, + onCheckboxChange: PropTypes.func.isRequired, + onOpenEditModal: PropTypes.func.isRequired +} + +module.exports = JourneyPattern diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js new file mode 100644 index 000000000..160631697 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js @@ -0,0 +1,38 @@ +var React = require('react') +var Component = require('react').Component +var PropTypes = require('react').PropTypes +var JourneyPattern = require('./JourneyPattern') + +class JourneyPatterns extends Component{ + constructor(props){ + super(props) + } + + componentDidMount() { + this.props.onLoadFirstPage() + } + + render() { + return ( + <div className='list-group'> + {this.props.journeyPatterns.map((journeyPattern, index) => + <JourneyPattern + value={ journeyPattern } + key={ index } + onCheckboxChange= {(e) => this.props.onCheckboxChange(e, index)} + onOpenEditModal= {() => this.props.onOpenEditModal(index, journeyPattern)} + /> + )} + </div> + ) + } +} + +JourneyPatterns.propTypes = { + journeyPatterns: PropTypes.array.isRequired, + onCheckboxChange: PropTypes.func.isRequired, + onLoadFirstPage: PropTypes.func.isRequired, + onOpenEditModal: PropTypes.func.isRequired +} + +module.exports = JourneyPatterns diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/containers/AddJourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/containers/AddJourneyPattern.js new file mode 100644 index 000000000..eb4499e50 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/containers/AddJourneyPattern.js @@ -0,0 +1,28 @@ +var actions = require('../actions') +var connect = require('react-redux').connect +var CreateModal = require('../components/CreateModal') + +const mapStateToProps = (state) => { + return { + modal: state.modal, + journeyPatterns: state.journeyPatterns + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onModalClose: () =>{ + dispatch(actions.closeModal()) + }, + onAddJourneyPattern: (data) =>{ + dispatch(actions.addJourneyPattern(data)) + }, + onOpenCreateModal: () =>{ + dispatch(actions.openCreateModal()) + } + } +} + +const AddJourneyPattern = connect(mapStateToProps, mapDispatchToProps)(CreateModal) + +module.exports = AddJourneyPattern diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/containers/ConfirmModal.js b/app/assets/javascripts/es6_browserified/journey_patterns/containers/ConfirmModal.js new file mode 100644 index 000000000..37f39176f --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/containers/ConfirmModal.js @@ -0,0 +1,24 @@ +var actions = require('../actions') +var connect = require('react-redux').connect +var ConfirmModal = require('../components/ConfirmModal') + +const mapStateToProps = (state) => { + return { + modal: state.modal + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onModal: (action) =>{ + dispatch(action) + }, + onModalClose: () =>{ + dispatch(actions.closeModal()) + } + } +} + +const ConfirmModalContainer = connect(mapStateToProps, mapDispatchToProps)(ConfirmModal) + +module.exports = ConfirmModalContainer diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/containers/JourneyPatternList.js b/app/assets/javascripts/es6_browserified/journey_patterns/containers/JourneyPatternList.js new file mode 100644 index 000000000..73dc6a1c7 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/containers/JourneyPatternList.js @@ -0,0 +1,27 @@ +var actions = require('../actions') +var connect = require('react-redux').connect +var JourneyPatterns = require('../components/JourneyPatterns') + +const mapStateToProps = (state) => { + return { + journeyPatterns: state.journeyPatterns + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onLoadFirstPage: () =>{ + dispatch(actions.loadFirstPage(dispatch)) + }, + onCheckboxChange: (e, index) =>{ + dispatch(actions.updateCheckboxValue(e, index)) + }, + onOpenEditModal: (index, journeyPattern) =>{ + dispatch(actions.openEditModal(index, journeyPattern)) + } + } +} + +const JourneyPatternList = connect(mapStateToProps, mapDispatchToProps)(JourneyPatterns) + +module.exports = JourneyPatternList diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/containers/Modal.js b/app/assets/javascripts/es6_browserified/journey_patterns/containers/Modal.js new file mode 100644 index 000000000..4b1809fa1 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/containers/Modal.js @@ -0,0 +1,29 @@ +var connect = require('react-redux').connect +var EditModal = require('../components/EditModal') +var CreateModal = require('../components/CreateModal') +var actions = require('../actions') + +const mapStateToProps = (state) => { + return { + modal: state.modal, + journeyPattern: state.journeyPattern + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onModalClose: () =>{ + dispatch(actions.closeModal()) + }, + saveModal: (index, data) =>{ + dispatch(actions.saveModal(index, data)) + }, + onDeleteJourneyPattern: (index) =>{ + dispatch(actions.deleteJourneyPattern(index)) + } + } +} + +const ModalContainer = connect(mapStateToProps, mapDispatchToProps)(EditModal, CreateModal) + +module.exports = ModalContainer diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/containers/Navigate.js b/app/assets/javascripts/es6_browserified/journey_patterns/containers/Navigate.js new file mode 100644 index 000000000..1c9f7113f --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/containers/Navigate.js @@ -0,0 +1,49 @@ +var React = require('react') +var connect = require('react-redux').connect +var actions = require('../actions') + +let Navigate = ({ dispatch, journeyPatterns, page, length, onOpenConfirmModal }) => { + let firstPage = 1 + let lastPage = Math.ceil(length / 12) + + return ( + <form className='btn-group btn-group-sm' onSubmit={e => { + e.preventDefault() + }}> + <button + onClick={e => { + e.preventDefault() + dispatch(actions.openConfirmModal(actions.goToPreviousPage(dispatch, page), actions.goToPreviousPage(dispatch, page))) + }} + type="submit" + data-toggle='modal' + data-target='#ConfirmModal' + className={ (page == firstPage ? "hidden" : "") + " btn btn-default" }> + <span className="fa fa-chevron-left"></span> + </button> + <button + onClick={e => { + e.preventDefault() + dispatch(actions.openConfirmModal(actions.goToNextPage(dispatch, page), actions.goToNextPage(dispatch, page))) + }} + type="submit" + data-toggle='modal' + data-target='#ConfirmModal' + className={ (page == lastPage ? "hidden" : "") + " btn btn-default" }> + <span className="fa fa-chevron-right"></span> + </button> + </form> + ) +} +const mapStateToProps = (state) => { + return { + journeyPatterns: state.journeyPatterns, + page: state.pagination.page, + length: state.pagination.totalCount, + confirmModalActions: state.modal.confirmActions + } +} + +Navigate = connect(mapStateToProps)(Navigate) + +module.exports = Navigate diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/containers/SaveJourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/containers/SaveJourneyPattern.js new file mode 100644 index 000000000..041219f0d --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/containers/SaveJourneyPattern.js @@ -0,0 +1,31 @@ +var React = require('react') +var connect = require('react-redux').connect +var actions = require('../actions') + +let SaveJourneyPattern = ({ dispatch, journeyPatterns, page }) => { + return ( + <form className='clearfix' onSubmit={e => {e.preventDefault()}}> + <button + className='btn btn-danger pull-right' + type='submit' + onClick={e => { + e.preventDefault() + dispatch(actions.savePage(dispatch, page)) + }} + > + Valider + </button> + </form> + ) +} + +const mapStateToProps = (state) => { + return { + journeyPatterns: state.journeyPatterns, + page: state.pagination.page + } +} + +SaveJourneyPattern = connect(mapStateToProps)(SaveJourneyPattern) + +module.exports = SaveJourneyPattern diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/index.js new file mode 100644 index 000000000..41e27d9d1 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/index.js @@ -0,0 +1,39 @@ +var React = require('react') +var render = require('react-dom').render +var Provider = require('react-redux').Provider +var createStore = require('redux').createStore +var journeyPatternsApp = require('./reducers') +var App = require('./components/App') + +// logger, DO NOT REMOVE +var applyMiddleware = require('redux').applyMiddleware +var createLogger = require('redux-logger') +var thunkMiddleware = require('redux-thunk').default +var promise = require('redux-promise') + +var initialState = { + journeyPatterns: [], + pagination: { + page : 1, + totalCount: window.journeyPatternLength + }, + modal: { + type: '', + modalProps: {}, + confirmModal: {} + } +} +const loggerMiddleware = createLogger() + +let store = createStore( + journeyPatternsApp, + initialState, + applyMiddleware(thunkMiddleware, promise, loggerMiddleware) +) + +render( + <Provider store={store}> + <App /> + </Provider>, + document.getElementById('journey_patterns') +) diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/index.js new file mode 100644 index 000000000..9e1d15e08 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/index.js @@ -0,0 +1,12 @@ +var combineReducers = require('redux').combineReducers +var journeyPatterns = require('./journeyPatterns') +var pagination = require('./pagination') +var modal = require('./modal') + +const journeyPatternsApp = combineReducers({ + journeyPatterns, + pagination, + modal +}) + +module.exports = journeyPatternsApp diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js new file mode 100644 index 000000000..96f6bd8c2 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js @@ -0,0 +1,87 @@ +var actions = require("../actions") + +const journeyPattern = (state = {}, action) => { + switch (action.type) { + case 'ADD_JOURNEYPATTERN': + const stop_points = state[0].stop_points.map((s)=>{ + s.checked = false + return s + }) + return { + name: action.data.name.value, + published_name: action.data.published_name.value, + registration_number: action.data.registration_number.value, + stop_points: stop_points, + deletable: false + } + case 'UPDATE_CHECKBOX_VALUE': + var updatedStopPoints = state.stop_points.map((s) => { + if (String(s.id) == action.id) { + return Object.assign({}, s, {checked : !s.checked}) + }else { + return s + } + }) + return Object.assign({}, state, {stop_points: updatedStopPoints}) + default: + return state + } +} + +const journeyPatterns = (state = [], action) => { + switch (action.type) { + case 'RECEIVE_JOURNEY_PATTERNS': + return [...action.json] + case 'LOAD_FIRST_PAGE': + actions.fetchJourneyPatterns(action.dispatch) + case 'GO_TO_PREVIOUS_PAGE': + if(action.currentPage > 1){ + actions.fetchJourneyPatterns(action.dispatch, action.currentPage, action.nextPage) + } + return state + case 'GO_TO_NEXT_PAGE': + if (window.journeyPatternLength - (action.currentPage * 12) > 0){ + actions.fetchJourneyPatterns(action.dispatch, action.currentPage, action.nextPage) + } + return state + case 'UPDATE_CHECKBOX_VALUE': + return state.map((j, i) =>{ + if(i == action.index) { + return journeyPattern(j, action) + } else { + return j + } + }) + case 'DELETE_JOURNEYPATTERN': + return state.map((j, i) =>{ + if(i == action.index) { + return Object.assign({}, j, {deletable: true}) + } else { + return j + } + }) + case 'ADD_JOURNEYPATTERN': + return [ + ...state, + journeyPattern(state, action) + ] + case 'SAVE_MODAL': + return state.map((j, i) =>{ + if(i == action.index) { + return Object.assign({}, j, { + name: action.data.name.value, + published_name: action.data.published_name.value, + registration_number: action.data.registration_number.value + }) + } else { + return j + } + }) + case 'SAVE_PAGE': + actions.submitJourneyPattern(action.dispatch, state) + default: + return state + } +} + +module.exports = journeyPatterns diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js new file mode 100644 index 000000000..85df48954 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js @@ -0,0 +1,41 @@ +const modal = (state = {}, action) => { + switch (action.type) { + case 'OPEN_CONFIRM_MODAL': + return Object.assign({}, state, { + type: 'confirm', + confirmModal: { + accept: action.accept, + cancel: action.cancel + } + }) + case 'EDIT_JOURNEYPATTERN_MODAL': + return { + type: 'edit', + modalProps: { + index: action.index, + journeyPattern: action.journeyPattern + }, + confirmModal: {} + } + case 'CREATE_JOURNEYPATTERN_MODAL': + return { + type: 'create', + modalProps: {}, + confirmModal: {} + } + case 'DELETE_JOURNEYPATTERN': + return Object.assign({}, state, { type: '' }) + case 'SAVE_MODAL': + return Object.assign({}, state, { type: '' }) + case 'CLOSE_MODAL': + return { + type: '', + modalProps: {}, + confirmModal: {} + } + default: + return state + } +} + +module.exports = modal diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js new file mode 100644 index 000000000..a17e9f292 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js @@ -0,0 +1,18 @@ +const pagination = (state = {}, action) => { + switch (action.type) { + case 'GO_TO_PREVIOUS_PAGE': + if (action.currentPage > 1){ + return Object.assign({}, state, {page : action.currentPage - 1}) + } + return state + case 'GO_TO_NEXT_PAGE': + if (state.totalCount - (action.currentPage * 12) > 0){ + return Object.assign({}, state, {page : action.currentPage + 1}) + } + return state + default: + return state + } +} + +module.exports = pagination diff --git a/app/assets/javascripts/sidemenu.coffee b/app/assets/javascripts/sidemenu.coffee new file mode 100644 index 000000000..d55096eab --- /dev/null +++ b/app/assets/javascripts/sidemenu.coffee @@ -0,0 +1,6 @@ +@mainmenu = -> + $('#main_nav').each -> + $(this).on 'click', '.toggleMenu', (e) -> + $(this).parent().toggleClass 'open' + +$(document).on 'ready turbolinks:load', mainmenu diff --git a/app/assets/javascripts/widget_bar.coffee b/app/assets/javascripts/widget_bar.coffee new file mode 100644 index 000000000..b06d574ed --- /dev/null +++ b/app/assets/javascripts/widget_bar.coffee @@ -0,0 +1,6 @@ +@widget_bar = -> + $('#widget_bar').each -> + $(this).on 'click', '.toggleWidgets', (e) -> + $(this).parent().toggleClass 'open' + +$(document).on 'ready turbolinks:load', widget_bar diff --git a/app/assets/stylesheets/application.sass.erb b/app/assets/stylesheets/application.sass.erb index d18ac0978..fde5badb1 100644 --- a/app/assets/stylesheets/application.sass.erb +++ b/app/assets/stylesheets/application.sass.erb @@ -26,7 +26,6 @@ $body-bg: #eee @import 'font-awesome-sprockets' @import 'font-awesome' @import 'jquery-ui' -@import 'morrisjs' @import 'formtastic' @import 'eonasdan-bootstrap-datetimepicker' @import 'footable' diff --git a/app/assets/stylesheets/application_new.sass b/app/assets/stylesheets/application_new.sass new file mode 100644 index 000000000..e3aeee56b --- /dev/null +++ b/app/assets/stylesheets/application_new.sass @@ -0,0 +1,6 @@ +//----------// +// Custom // +//----------// + +@import 'new/layout' +@import 'new/components/*' diff --git a/app/assets/stylesheets/base.sass b/app/assets/stylesheets/base.sass new file mode 100644 index 000000000..3035fd64c --- /dev/null +++ b/app/assets/stylesheets/base.sass @@ -0,0 +1,15 @@ +//-------------// +// Libraries // +//-------------// + +// Bootstrap +@import 'bootstrap-sass-official/_bootstrap-sprockets.scss' +@import 'bootstrap-sass-official' + +// FontAwesome +@import 'font-awesome-sprockets' +@import 'font-awesome' + +// Select2 +@import 'select2' +@import 'select2-bootstrap' diff --git a/app/assets/stylesheets/main/calendars.sass b/app/assets/stylesheets/main/calendars.sass new file mode 100644 index 000000000..298ce2a62 --- /dev/null +++ b/app/assets/stylesheets/main/calendars.sass @@ -0,0 +1,11 @@ +#calendar_form + .btn + margin: 5px + #delete-btn + margin-top: 23px + .well + padding-left: 50px + +#calendar_search_form + button + margin-top: 24px diff --git a/app/assets/stylesheets/main/time_tables.sass b/app/assets/stylesheets/main/time_tables.sass index b24a02c27..de2ae8253 100644 --- a/app/assets/stylesheets/main/time_tables.sass +++ b/app/assets/stylesheets/main/time_tables.sass @@ -61,6 +61,9 @@ .actions float: right + #associated_calendars + padding-top: 15px + #workspace.time_tables.edit, #workspace.time_tables.new, #workspace.time_tables.create, @@ -129,4 +132,4 @@ background: url(image-path('icons/remove.png')) no-repeat 0% 50% .actions - margin-top: 20px
\ No newline at end of file + margin-top: 20px diff --git a/app/assets/stylesheets/new/components/_main_nav.sass b/app/assets/stylesheets/new/components/_main_nav.sass new file mode 100644 index 000000000..f766f197d --- /dev/null +++ b/app/assets/stylesheets/new/components/_main_nav.sass @@ -0,0 +1,132 @@ +#main_nav + display: block + // To avoid white spaces between childrend inline-block + letter-spacing: -0.31em + text-rendering: optimizespeed + font-weight: 300 + height: 50px + width: 100% + background-color: #fafafa + border-bottom: 1px solid darken(#fafafa, 10%) + // Main nav is fixed to top + position: fixed + top: 0 + left: 0 + right: 0 + z-index: 999 + + > * + display: inline-block + // To avoid white spaces between children inline-block + letter-spacing: normal + word-spacing: normal + text-rendering: auto + overflow: hidden + vertical-align: middle + height: 49px + width: calc(100% - 200px) + padding: 15px + + .nav-menu + width: 50px + text-align: center + background-color: #fff + border-right: 1px solid darken(#fafafa, 10%) + cursor: pointer + + .nav-right + padding: 0 + margin: 0 + width: 150px + + > li + display: inline-block + text-align: center + + > a + display: block + border-left: 1px solid darken(#fafafa, 10%) + padding: 15px + width: 50px + height: 50px + +#main_nav .nav-menu + padding: 0 + + .toggleMenu + display: inline-block + padding: 15px + transform: rotate(0deg) + transition: 0.3s + font: normal normal normal 14px/1 FontAwesome + text-rendering: auto + -webkit-font-smoothing: antialiased + font-size: 1.3333em + list-style: 0.75em + visibility: -15% + + &:before + content: '\f0c9' + + .menu-content + display: block + text-align: left + width: 280px + margin: 0 0 0 -280px + padding: 0 + position: fixed + z-index: 998 + top: 50px + left: 0 + bottom: 0 + border-right: 1px solid darken(#fafafa, 10%) + background-color: #fff + transition: 0.3s + + > li > a + display: block + border-bottom: 1px solid darken(#fafafa, 10%) + + &.open + .toggleMenu + transform: rotate(-90deg) + + .menu-content + margin-left: 0 + + // Details of menu-content list items + .menu-content + .brand + display: block + padding: 15px + border-bottom: 1px solid darken(#fafafa, 10%) + + .brandname + font-size: 1.5em + + .mc-item + .mci-icon + display: inline-block + vertical-align: middle + padding: 15px + width: 50px + + .mci-desc + display: inline-block + vertical-align: middle + padding: 15px + width: calc(100% - 50px) + border-left: 1px solid darken(#fafafa, 10%) + + h4 + margin: 0 + + + * + display: inline-block + margin-top: 0.5em + +#main_nav .breadcrumb + padding: 0 + margin: 0 + background-color: transparent + border-radius: none diff --git a/app/assets/stylesheets/new/components/_widget_bar.sass b/app/assets/stylesheets/new/components/_widget_bar.sass new file mode 100644 index 000000000..3cef0af17 --- /dev/null +++ b/app/assets/stylesheets/new/components/_widget_bar.sass @@ -0,0 +1,104 @@ +#widget_bar + .toggleWidgets + display: inline-block + position: fixed + z-index: 997 + top: 65px + right: 15px + padding: 8px + transform: rotate(0deg) + transition: 0.3s + font: normal normal normal 14px/1 FontAwesome + text-rendering: auto + -webkit-font-smoothing: antialiased + font-size: 1em + color: #fff + background-color: #3c3c3c + border-radius: 50% + cursor: pointer + + &:before + content: '\f0ae' + + .widget-list + display: block + margin: 0 -280px 0 0 + padding: 0 + width: 280px + position: fixed + z-index: 996 + top: 110px + right: 0 + bottom: 0 + transition: 0.3s + + > li + display: block + + &.open + .toggleWidgets + transform: rotate(-90deg) + + .widget-list + margin-right: 0 + + + .container-fluid + padding-right: 295px + transition: 0.3s + +#widget_bar .widget-list + margin-bottom: 0 + background-color: #3c3c3c + color: #fff + + .panel, .panel.panel-default + border-radius: 0 + border: none + background-color: transparent + color: inherit + box-shadow: none + + + .panel + margin-top: 0 + + > .panel-heading + border-radius: 0 + border: 0 + border-bottom: 1px solid lighten(#3c3c3c, 10%) + background-color: darken(#3c3c3c, 10%) + color: inherit + padding: 0 + + .panel-title + font-weight: bold + + > a + display: block + position: relative + padding: 15px + + &:hover, &:focus + text-decoration: none + + &:after + content: '\f078' + display: inline-block + transform: rotate(180deg) + transition: 0.3s + font: normal normal normal 14px/1 FontAwesome + text-rendering: auto + -webkit-font-smoothing: antialiased + font-size: 1.3333em + list-style: 0.75em + visibility: -15% + position: absolute + right: 15px + + &.collapsed, &[aria-expanded='false'] + &:after + transform: rotate(0deg) + + + .panel-body + padding: 15px + border: 0 diff --git a/app/assets/stylesheets/new/layout.sass b/app/assets/stylesheets/new/layout.sass new file mode 100644 index 000000000..9e460406b --- /dev/null +++ b/app/assets/stylesheets/new/layout.sass @@ -0,0 +1,14 @@ +//----------// +// Layout // +//----------// + +html + box-sizing: border-box + + * + box-sizing: inherit + +body + padding-top: 65px /* Because main nav is fixed to top */ + // background-color: #fafafa + // color: #3c3c3c diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c2414f5bb..b616def70 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,6 +2,9 @@ class ApplicationController < ActionController::Base include Pundit rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized + # Comment to activate the new layout + # layout 'application_new' + # TODO : Delete hack to authorize Cross Request for js and json get request from javascript protect_from_forgery unless: -> { request.get? && (request.format.json? || request.format.js?) } before_action :authenticate_user! diff --git a/app/controllers/autocomplete_stop_areas_controller.rb b/app/controllers/autocomplete_stop_areas_controller.rb index b653e6cb5..cd7123efd 100644 --- a/app/controllers/autocomplete_stop_areas_controller.rb +++ b/app/controllers/autocomplete_stop_areas_controller.rb @@ -14,25 +14,20 @@ class AutocompleteStopAreasController < InheritedResources::Base protected def collection - result = [] - if physical_filter? - result = referential.stop_areas.physical - elsif itl_exclude_filter? - result = Chouette::StopArea.where("area_type != 'ITL'") - elsif target_type? && relation_parent? - result = Chouette::StopArea.new( :area_type => params[ :target_type ] ).possible_parents - elsif target_type? && relation_children? - result = Chouette::StopArea.new( :area_type => params[ :target_type ] ).possible_children - else - result = referential.stop_areas + scope = referential.stop_areas + scope = scope.physical if physical_filter? + if target_type? + scope = scope.where(area_type: params[:target_type]) + scope = scope.possible_parents if relation_parent? + scope = scope.possible_parents if relation_children? end args = [].tap{|arg| 3.times{arg << "%#{params[:q]}%"}} - @stop_areas = result.where("name ILIKE ? OR registration_number ILIKE ? OR objectid ILIKE ?", *args).limit(50) + @stop_areas = scope.where("name ILIKE ? OR registration_number ILIKE ? OR objectid ILIKE ?", *args).limit(50) @stop_areas end def target_type? - params.has_key?( :target_type) && params.has_key?( :relation ) + params.has_key?( :target_type) end def relation_parent? @@ -43,12 +38,7 @@ class AutocompleteStopAreasController < InheritedResources::Base params[ :relation ] == "children" end - def itl_exclude_filter? - params[:filter] == "itl_excluded" - end - def physical_filter? params[:filter] == "physical" end - end diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb new file mode 100644 index 000000000..9784820f9 --- /dev/null +++ b/app/controllers/calendars_controller.rb @@ -0,0 +1,47 @@ +class CalendarsController < BreadcrumbController + defaults resource_class: Calendar + before_action :check_policy, only: [:edit, :update, :destroy] + + respond_to :html + respond_to :js, only: :index + + private + def calendar_params + permitted_params = [:id, :name, :short_name, periods_attributes: [:id, :begin, :end, :_destroy], date_values_attributes: [:id, :value, :_destroy]] + permitted_params << :shared if policy(Calendar).share? + params.require(:calendar).permit(*permitted_params) + end + + def sort_column + Calendar.column_names.include?(params[:sort]) ? params[:sort] : 'short_name' + end + + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + + protected + def resource + @calendar = Calendar.where('organisation_id = ? OR shared = true', current_organisation.id).find_by_id(params[:id]) + end + + def build_resource + super.tap do |calendar| + calendar.organisation = current_organisation + end + end + + def collection + return @calendars if @calendars + + @q = Calendar.where('organisation_id = ? OR shared = true', current_organisation.id).search(params[:q]) + calendars = @q.result + calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction + @calendars = calendars.paginate(page: params[:page]) + end + + def check_policy + authorize resource + end +end + diff --git a/app/controllers/chouette_controller.rb b/app/controllers/chouette_controller.rb index 46691b13e..074fc0515 100644 --- a/app/controllers/chouette_controller.rb +++ b/app/controllers/chouette_controller.rb @@ -2,15 +2,18 @@ class ChouetteController < BreadcrumbController include ApplicationHelper include BreadcrumbHelper - + before_action :switch_referential - + def switch_referential Apartment::Tenant.switch!(referential.slug) - end + end def referential - @referential ||= current_organisation.referentials.find params[:referential_id] - end + @referential ||= current_organisation.referentials.find params[:referential_id] + end + alias_method :current_referential, :referential + helper_method :current_referential + end diff --git a/app/controllers/companies_controller.rb b/app/controllers/companies_controller.rb index 842398552..bf298786a 100644 --- a/app/controllers/companies_controller.rb +++ b/app/controllers/companies_controller.rb @@ -34,8 +34,12 @@ class CompaniesController < BreadcrumbController protected def collection @q = line_referential.companies.search(params[:q]) - @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) - @decoratedcompanies = CompanyDecorator.decorate_collection(@companies) + + if sort_column && sort_direction + @companies ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page]) + else + @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + end end @@ -53,8 +57,20 @@ class CompaniesController < BreadcrumbController authorize resource end + alias_method :current_referential, :line_referential + helper_method :current_referential + def company_params params.require(:company).permit( :objectid, :object_version, :creation_time, :creator_id, :name, :short_name, :organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :registration_number, :url, :time_zone ) end + private + + def sort_column + line_referential.companies.column_names.include?(params[:sort]) ? params[:sort] : 'name' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + end diff --git a/app/controllers/journey_patterns_collections_controller.rb b/app/controllers/journey_patterns_collections_controller.rb new file mode 100644 index 000000000..39355932e --- /dev/null +++ b/app/controllers/journey_patterns_collections_controller.rb @@ -0,0 +1,51 @@ +class JourneyPatternsCollectionsController < ChouetteController + respond_to :html + respond_to :json + + belongs_to :referential do + belongs_to :line, :parent_class => Chouette::Line do + belongs_to :route, :parent_class => Chouette::Route + end + end + alias_method :route, :parent + + def show + journey_patterns_state + end + + def update + state = JSON.parse request.raw_post + state.each do |item| + journey_pattern = journey_pattern_by_objectid(item['object_id']) + journey_pattern_update_stop_points(journey_pattern, item['stop_points']) if journey_pattern + end + + journey_patterns_state + end + + protected + + def journey_pattern_update_stop_points journey_pattern, stop_points + stop_points.each do |sp| + stop_id = sp['id'] + exist = journey_pattern.stop_area_ids.include?(stop_id) + next if exist && sp['checked'] + + stop_point = route.stop_points.find_by(stop_area_id: stop_id) + if sp['checked'] && !exist + journey_pattern.stop_points << stop_point + else + journey_pattern.stop_points.delete(stop_point) + end + end + end + + def journey_patterns_state + @q = route.journey_patterns.includes(:stop_points) + @journey_patterns ||= @q.paginate(:page => params[:page]).order(:name) + end + + def journey_pattern_by_objectid objectid + Chouette::JourneyPattern.find_by(objectid: objectid) + end +end diff --git a/app/controllers/line_footnotes_controller.rb b/app/controllers/line_footnotes_controller.rb new file mode 100644 index 000000000..305a8fac3 --- /dev/null +++ b/app/controllers/line_footnotes_controller.rb @@ -0,0 +1,40 @@ +class LineFootnotesController < ChouetteController + defaults :resource_class => Chouette::Line, :instance_name => 'line' + before_action :check_policy, :only => [:edit, :update] + belongs_to :referential + + def show + show! do + build_breadcrumb :show + end + end + + def edit + edit! do + build_breadcrumb :edit + end + end + + def update + if @line.update(line_params) + redirect_to referential_line_footnotes_path(@referential, @line) , notice: t('notice.footnotes.updated') + else + render :edit + end + end + + private + def check_policy + authorize resource, :update_footnote? + end + + def resource + @referential = Referential.find params[:referential_id] + @line = @referential.lines.find params[:line_id] + end + + def line_params + params.require(:line).permit( + { footnotes_attributes: [ :code, :label, :_destroy, :id ] } ) + end +end diff --git a/app/controllers/lines_controller.rb b/app/controllers/lines_controller.rb index c4d7bffa5..9a0a007aa 100644 --- a/app/controllers/lines_controller.rb +++ b/app/controllers/lines_controller.rb @@ -79,16 +79,32 @@ class LinesController < BreadcrumbController end end @q = line_referential.lines.search(params[:q]) - @lines ||= @q.result(:distinct => true).order(:number).paginate(:page => params[:page]).includes([:network, :company]) + + if sort_column && sort_direction + @lines ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page]).includes([:network, :company]) + else + @lines ||= @q.result(:distinct => true).order(:number).paginate(:page => params[:page]).includes([:network, :company]) + end end alias_method :line_referential, :parent private + + def sort_column + line_referential.lines.column_names.include?(params[:sort]) ? params[:sort] : 'number' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + def check_policy authorize resource end + alias_method :current_referential, :line_referential + helper_method :current_referential + def line_params params.require(:line).permit( :transport_mode, :network_id, :company_id, :objectid, :object_version, :creation_time, :creator_id, :name, :number, :published_name, :transport_mode, :registration_number, :comment, :mobility_restricted_suitability, :int_user_needs, :flexible_service, :group_of_lines, :group_of_line_ids, :group_of_line_tokens, :url, :color, :text_color, :stable_id, { footnotes_attributes: [ :code, :label, :_destroy, :id ] } ) end diff --git a/app/controllers/networks_controller.rb b/app/controllers/networks_controller.rb index 85ec36769..d9070e7e8 100644 --- a/app/controllers/networks_controller.rb +++ b/app/controllers/networks_controller.rb @@ -40,7 +40,12 @@ class NetworksController < BreadcrumbController def collection @q = line_referential.networks.search(params[:q]) - @networks ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + + if sort_column && sort_direction + @networks ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page]) + else + @networks ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + end end def resource_url(network = nil) @@ -57,7 +62,20 @@ class NetworksController < BreadcrumbController authorize resource end + alias_method :current_referential, :line_referential + helper_method :current_referential + def network_params params.require(:network).permit(:objectid, :object_version, :creation_time, :creator_id, :version_date, :description, :name, :registration_number, :source_name, :source_type_name, :source_identifier, :comment ) end + + private + + def sort_column + line_referential.networks.column_names.include?(params[:sort]) ? params[:sort] : 'name' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + end diff --git a/app/controllers/referential_companies_controller.rb b/app/controllers/referential_companies_controller.rb index a369488ba..882796951 100644 --- a/app/controllers/referential_companies_controller.rb +++ b/app/controllers/referential_companies_controller.rb @@ -28,7 +28,12 @@ class ReferentialCompaniesController < ChouetteController def collection @q = referential.workbench.companies.search(params[:q]) - @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + + if sort_column && sort_direction + @companies ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page]) + else + @companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + end end def resource_url(company = nil) @@ -42,4 +47,14 @@ class ReferentialCompaniesController < ChouetteController def company_params params.require(:company).permit( :objectid, :object_version, :creation_time, :creator_id, :name, :short_name, :organizational_unit, :operating_department_name, :code, :phone, :fax, :email, :registration_number, :url, :time_zone ) end + + private + + def sort_column + referential.workbench.companies.column_names.include?(params[:sort]) ? params[:sort] : 'name' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + end diff --git a/app/controllers/referential_lines_controller.rb b/app/controllers/referential_lines_controller.rb index cfa5ce143..4ffee27cb 100644 --- a/app/controllers/referential_lines_controller.rb +++ b/app/controllers/referential_lines_controller.rb @@ -1,4 +1,5 @@ class ReferentialLinesController < ChouetteController + before_action :check_policy, :only => [:edit, :update, :destroy] defaults :resource_class => Chouette::Line, :collection_name => 'lines', :instance_name => 'line' respond_to :html @@ -76,11 +77,28 @@ class ReferentialLinesController < ChouetteController end @q = referential.lines.search(params[:q]) - @lines ||= @q.result(:distinct => true).order(:number).paginate(:page => params[:page]).includes([:network, :company]) + + if sort_column && sort_direction + @lines ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page]).includes([:network, :company]) + else + @lines ||= @q.result(:distinct => true).order(:number).paginate(:page => params[:page]).includes([:network, :company]) + end + end private + def sort_column + referential.lines.column_names.include?(params[:sort]) ? params[:sort] : 'number' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + + def check_policy + authorize resource + end + def line_params params.require(:line).permit( :transport_mode, @@ -105,8 +123,8 @@ class ReferentialLinesController < ChouetteController :url, :color, :text_color, - :stable_id, - { footnotes_attributes: [ :code, :label, :_destroy, :id ] } ) + :stable_id + ) end end diff --git a/app/controllers/referential_networks_controller.rb b/app/controllers/referential_networks_controller.rb index 00c680c65..711b0cc69 100644 --- a/app/controllers/referential_networks_controller.rb +++ b/app/controllers/referential_networks_controller.rb @@ -36,7 +36,12 @@ class ReferentialNetworksController < ChouetteController def collection @q = referential.workbench.networks.search(params[:q]) - @networks ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + + if sort_column && sort_direction + @networks ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page]) + else + @networks ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page]) + end end def resource_url(network = nil) @@ -51,4 +56,13 @@ class ReferentialNetworksController < ChouetteController params.require(:network).permit(:objectid, :object_version, :creation_time, :creator_id, :version_date, :description, :name, :registration_number, :source_name, :source_type_name, :source_identifier, :comment ) end + private + + def sort_column + referential.workbench.networks.column_names.include?(params[:sort]) ? params[:sort] : 'name' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + end diff --git a/app/controllers/referential_stop_areas_controller.rb b/app/controllers/referential_stop_areas_controller.rb index e0eae9aed..8f0d6fea3 100644 --- a/app/controllers/referential_stop_areas_controller.rb +++ b/app/controllers/referential_stop_areas_controller.rb @@ -120,16 +120,37 @@ class ReferentialStopAreasController < ChouetteController def collection @q = parent.present? ? parent.stop_areas.search(params[:q]) : referential.stop_areas.search(params[:q]) - @stop_areas ||= - begin - stop_areas = @q.result(:distinct => true).order(:name) - stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? - stop_areas - end + + if sort_column && sort_direction + @stop_areas ||= + begin + stop_areas = @q.result(:distinct => true).order(sort_column + ' ' + sort_direction) + stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? + stop_areas + end + else + @stop_areas ||= + begin + stop_areas = @q.result(:distinct => true).order(:name) + stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? + stop_areas + end + end end private + def sort_column + if parent.present? + parent.stop_areas.include?(params[:sort]) ? params[:sort] : 'name' + else + referential.stop_areas.include?(params[:sort]) ? params[:sort] : 'name' + end + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + def stop_area_params params.require(:stop_area).permit( :routing_stop_ids, :routing_line_ids, :children_ids, :stop_area_type, :parent_id, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :area_type, :registration_number, :nearest_topic_name, :fare_code, :longitude, :latitude, :long_lat_type, :country_code, :street_name, :zip_code, :city_name, :mobility_restricted_suitability, :stairs_availability, :lift_availability, :int_user_needs, :coordinates, :url, :time_zone ) end diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index f9749b837..23eb6263d 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -1,6 +1,6 @@ class ReferentialsController < BreadcrumbController - defaults :resource_class => Referential + before_action :check_policy, :only => [:edit, :update] respond_to :html respond_to :json, :only => :show @@ -31,6 +31,8 @@ class ReferentialsController < BreadcrumbController } format.html { build_breadcrumb :show} end + @reflines = lines_collection.paginate(page: params[:page], per_page: 10) + # resource.lines.paginate(page: params[:page], per_page: 10) end def edit @@ -74,6 +76,26 @@ class ReferentialsController < BreadcrumbController @referentials ||= current_organisation.referentials.order(:name) end + def lines_collection + @q = resource.lines.search(params[:q]) + + if sort_column && sort_direction + @reflines ||= + begin + reflines = @q.result(distinct: true).order(sort_column + ' ' + sort_direction) + reflines = reflines.paginate(page: params[:page], per_page: 10) + reflines + end + else + @reflines ||= + begin + reflines = @q.result(distinct: true).order(:name) + reflines = reflines.paginate(page: params[:page], per_page: 10) + reflines + end + end + end + def build_resource super.tap do |referential| referential.user_id = current_user.id @@ -87,6 +109,17 @@ class ReferentialsController < BreadcrumbController end private + def sort_column + resource.lines.include?(params[:sort]) ? params[:sort] : 'name' + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + + def check_policy + authorize resource + end + def referential_params params.require(:referential).permit( :id, diff --git a/app/controllers/routing_constraint_zones_controller.rb b/app/controllers/routing_constraint_zones_controller.rb new file mode 100644 index 000000000..1c2c40cbb --- /dev/null +++ b/app/controllers/routing_constraint_zones_controller.rb @@ -0,0 +1,15 @@ +class RoutingConstraintZonesController < ChouetteController + defaults resource_class: Chouette::RoutingConstraintZone + + respond_to :html, :xml, :json + + belongs_to :referential do + belongs_to :line, parent_class: Chouette::Line + end + + private + def routing_constraint_zone_params + params.require(:routing_constraint_zone).permit(:name, { stop_area_ids: [] }, :line_id, :objectid, :object_version, :creation_time, :creator_id) + end + +end diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index 1f55b1de8..fca33bdfb 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -139,16 +139,40 @@ class StopAreasController < BreadcrumbController def collection @q = parent.present? ? parent.stop_areas.search(params[:q]) : referential.stop_areas.search(params[:q]) - @stop_areas ||= - begin - stop_areas = @q.result.order(:name) - stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? - stop_areas - end + + if sort_column && sort_direction + @stop_areas ||= + begin + stop_areas = @q.result.order(sort_column + ' ' + sort_direction) + stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? + stop_areas + end + else + @stop_areas ||= + begin + stop_areas = @q.result.order(:name) + stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? + stop_areas + end + end end private + def sort_column + if parent.present? + parent.stop_areas.column_names.include?(params[:sort]) ? params[:sort] : 'name' + else + referential.stop_areas.column_names.include?(params[:sort]) ? params[:sort] : 'name' + end + end + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end + + alias_method :current_referential, :stop_area_referential + helper_method :current_referential + def stop_area_params params.require(:stop_area).permit( :routing_stop_ids, :routing_line_ids, :children_ids, :stop_area_type, :parent_id, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :area_type, :registration_number, :nearest_topic_name, :fare_code, :longitude, :latitude, :long_lat_type, :country_code, :street_name, :zip_code, :city_name, :mobility_restricted_suitability, :stairs_availability, :lift_availability, :int_user_needs, :coordinates, :url, :time_zone ) end diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb index 5ebd3c5c3..10e1e76dc 100644 --- a/app/controllers/time_tables_controller.rb +++ b/app/controllers/time_tables_controller.rb @@ -9,7 +9,6 @@ class TimeTablesController < ChouetteController belongs_to :referential def show - @year = params[:year] ? params[:year].to_i : Date.today.cwyear @time_table_combination = TimeTableCombination.new show! do @@ -24,6 +23,25 @@ class TimeTablesController < ChouetteController end end + def create + tt_params = time_table_params + if tt_params[:calendar_id] + %i(monday tuesday wednesday thursday friday saturday sunday).map { |d| tt_params[d] = true } + calendar = current_organisation.calendars.find_by_id(tt_params[:calendar_id]) + tt_params[:calendar_id] = nil if tt_params.has_key?(:dates_attributes) || tt_params.has_key?(:periods_attributes) + end + @time_table = Chouette::TimeTable.new(tt_params) + if calendar + calendar.dates.each_with_index do |date, i| + @time_table.dates << Chouette::TimeTableDate.new(date: date, position: i) + end + calendar.date_ranges.each_with_index do |date_range, i| + @time_table.periods << Chouette::TimeTablePeriod.new(period_start: date_range.begin, period_end: date_range.end, position: i) + end + end + create! + end + def edit edit! do build_breadcrumb :edit @@ -31,6 +49,12 @@ class TimeTablesController < ChouetteController end end + def update + @time_table = Chouette::TimeTable.find_by_id(params[:id]) + @time_table.calendar_id = nil + update! + end + def index request.format.kml? ? @per_page = nil : @per_page = 12 @@ -89,8 +113,8 @@ class TimeTablesController < ChouetteController end private - + def time_table_params - params.require(:time_table).permit( :objectid, :object_version, :creation_time, :creator_id, :version, :comment, :int_day_types, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday, :start_date, :end_date, { :dates_attributes => [:date, :in_out, :id, :_destroy] }, { :periods_attributes => [:period_start, :period_end, :_destroy, :id] }, :tag_list, :tag_search ) + params.require(:time_table).permit( :objectid, :object_version, :creation_time, :creator_id, :calendar_id, :version, :comment, :int_day_types, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday, :start_date, :end_date, { :dates_attributes => [:date, :in_out, :id, :_destroy] }, { :periods_attributes => [:period_start, :period_end, :_destroy, :id] }, :tag_list, :tag_search ) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 132b7dcaa..49bc67ce7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,6 +1,6 @@ module ApplicationHelper - include RefobjectsHelper + include NewfrontHelper def font_awesome_classic_tag(name) name = "fa-file-text-o" if name == "fa-file-csv-o" diff --git a/app/helpers/breadcrumb_helper.rb b/app/helpers/breadcrumb_helper.rb index 9d503fe2e..c973c754c 100644 --- a/app/helpers/breadcrumb_helper.rb +++ b/app/helpers/breadcrumb_helper.rb @@ -36,6 +36,10 @@ module BreadcrumbHelper route_section_breadcrumb action when "Chouette::Timeband" timeband_breadcrumb action + when 'Chouette::RoutingConstraintZone' + routing_constraint_zone_breadcrumb action + when 'Calendar' + calendar_breadcrumb action when "StopAreaCopy" stop_area_copy_breadcrumb action when "Import" @@ -68,6 +72,12 @@ module BreadcrumbHelper end end + def calendar_breadcrumb(action) + add_breadcrumb I18n.t('breadcrumbs.referentials'), referentials_path + add_breadcrumb I18n.t('calendars.index.title'), calendars_path + add_breadcrumb @calendar.name if %i(show edit).include? action + end + def workbench_breadcrumb(action) add_breadcrumb I18n.t("breadcrumbs.referentials"), referentials_path add_breadcrumb breadcrumb_label(@workbench), workbench_path(@workbench), :title => breadcrumb_tooltip(@workbench) @@ -159,6 +169,12 @@ module BreadcrumbHelper add_breadcrumb breadcrumb_label(@route), referential_line_route_path(@referential, @line,@route),:title => breadcrumb_tooltip(@route) if action == :edit end + def routing_constraint_zone_breadcrumb(action) + line_breadcrumb :edit + add_breadcrumb Chouette::RoutingConstraintZone.model_name.human.pluralize(:fr), referential_line_routing_constraint_zones_path(@referential, @line) unless action == :index + add_breadcrumb breadcrumb_label(@routing_constraint_zone), referential_line_routing_constraint_zone_path(@referential, @line, @routing_constraint_zone), title: breadcrumb_tooltip(@routing_constraint_zone) if %i(show edit).include? action + end + def journey_pattern_breadcrumb(action) route_breadcrumb :edit add_breadcrumb breadcrumb_label(@journey_pattern), referential_line_route_journey_pattern_path(@referential, @line,@route,@journey_pattern),:title => breadcrumb_tooltip(@journey_pattern) if action == :edit diff --git a/app/helpers/newfront_helper.rb b/app/helpers/newfront_helper.rb new file mode 100644 index 000000000..7bedbeea9 --- /dev/null +++ b/app/helpers/newfront_helper.rb @@ -0,0 +1,118 @@ +module NewfrontHelper + + # Table Builder + def table_builder collection, columns, actions, cls = nil + return unless collection.present? + + head = content_tag :thead do + content_tag :tr do + hcont = [] + columns.map do |k, v| + # hcont << content_tag(:th, k.to_s.titleize) + hcont << content_tag(:th, sortable_columns(collection, k)) + end + hcont << content_tag(:th, 'Actions', class: 'text-center') if actions.any? + + hcont.join.html_safe + end + end + + body = content_tag :tbody do + collection.collect do |item| + content_tag :tr do + bcont = [] + columns.map do |k, attribute| + value = + if Proc === attribute + attribute.call(item) + else + item.try(attribute) + end + bcont << content_tag(:td, value) + end + bcont << content_tag(:td, links_builder(item, actions), class: 'text-center') if actions.any? + + bcont.join.html_safe + end + end.join.html_safe + end + + content_tag :table, head + body, class: cls + end + + def links_builder(item, actions) + trigger = content_tag :div, class: 'btn btn-primary dropdown-toggle', data: { toggle: 'dropdown' } do + a = content_tag :span, '', class: 'fa fa-bars' + b = content_tag :span, '', class: 'caret' + a + b + end + + menu = content_tag :ul, class: 'dropdown-menu' do + actions.collect do |action| + polymorph_url = [] + + unless [:show, :delete].include? action + polymorph_url << action + end + + unless item.class.to_s == 'Calendar' + if current_referential + polymorph_url << current_referential + polymorph_url << item.line if item.respond_to? :line + elsif item.respond_to? :referential + polymorph_url << item.referential + elsif item.respond_to? :line_referential + polymorph_url << item.line_referential + end + end + + polymorph_url << item + + if action == :delete + if policy(item).present? + if policy(item).destroy? + content_tag :li, link_to(t("table.#{action}"), polymorph_url, method: :delete, data: { confirm: 'Etes-vous sûr(e) de vouloir effectuer cette action ?' }) + end + else + content_tag :li, link_to(t("table.#{action}"), polymorph_url, method: :delete, data: { confirm: 'Etes-vous sûr(e) de vouloir effectuer cette action ?' }) + end + + elsif action == :edit + if policy(item).present? + if policy(item).update? + content_tag :li, link_to(t("table.#{action}"), polymorph_url) + end + else + content_tag :li, link_to(t("table.#{action}"), polymorph_url) + end + else + content_tag :li, link_to(t("table.#{action}"), polymorph_url) + end + end.join.html_safe + end + + content_tag :div, trigger + menu, class: 'btn-group btn-group-xs' + + end + + def sortable_columns collection, key + direction = (key == params[:sort] && params[:direction] == 'desc') ? 'asc' : 'desc' + + icon = 'sort-desc' if direction == 'asc' + icon = 'sort-asc' if direction == 'desc' + + link_to({sort: key, direction: direction}) do + pic = content_tag :span, '', class: "fa fa-#{icon}", style: 'margin-left:5px' + (key.to_s.titleize + pic).html_safe + end + end + + # Replacement message + def replacement_msg text + content_tag :div, '', class: 'alert alert-warning' do + icon = content_tag :span, '', class: 'fa fa-lg fa-info-circle', style: 'margin-right:7px;' + icon + text + end + end + +end diff --git a/app/helpers/refobjects_helper.rb b/app/helpers/refobjects_helper.rb deleted file mode 100644 index aac40b944..000000000 --- a/app/helpers/refobjects_helper.rb +++ /dev/null @@ -1,62 +0,0 @@ -module RefobjectsHelper - - def table_builder collection, columns, actions = [], cls = nil - return unless collection.present? - - head = content_tag :thead do - content_tag :tr do - attributes_head = columns.collect do |col| - content_tag :th, col.to_s.titleize - end.join.html_safe - links_head = content_tag :th, "Actions" if actions.any? - attributes_head + links_head - end - end - - body = content_tag :tbody do - collection.collect { |item| - content_tag :tr do - attributes = columns.collect { |col| - content_tag(:td, item.try(col)) - }.join.html_safe - - # Build links - links = content_tag :td, autolinks_builder(item, actions, :xs), class: 'text-center' if actions.any? - - attributes + links - end - }.join.html_safe - end - - # content_tag :table, head + body, class: cls - content_tag :table, "pouet" - end - - def autolinks_builder(item, actions, cls) - link = [] - - actions.each do |action| - if action == "show" - showlink = link_to(company_path(item), class: 'btn btn-default') do - content_tag :span, "", class: 'fa fa-eye' - end - link << showlink - elsif action == "edit" - editlink = link_to(edit_company_path(item), class: 'btn btn-default') do - content_tag :span, "", class: 'fa fa-pencil' - end - link << editlink - elsif action == "delete" - deletelink = link_to(company_path(item), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-default') do - content_tag :span, "", class: 'fa fa-trash-o' - end - link << deletelink - end - end - - content_tag :div, class: "btn-group btn-group-#{cls}" do - link.join().html_safe - end - end - -end diff --git a/app/models/calendar.rb b/app/models/calendar.rb new file mode 100644 index 000000000..641f97302 --- /dev/null +++ b/app/models/calendar.rb @@ -0,0 +1,258 @@ +class Calendar < ActiveRecord::Base + belongs_to :organisation + has_many :time_tables + + validates_presence_of :name, :short_name, :organisation + validates_uniqueness_of :short_name + + after_initialize :init_dates_and_date_ranges + + scope :contains_date, ->(date) { where('date ? = any (dates) OR date ? <@ any (date_ranges)', date, date) } + + def init_dates_and_date_ranges + self.dates ||= [] + self.date_ranges ||= [] + end + + def self.ransackable_scopes(auth_object = nil) + [:contains_date] + end + + class Period + include ActiveAttr::Model + + attribute :id, type: Integer + attribute :begin, type: Date + attribute :end, type: Date + + validates_presence_of :begin, :end + validate :check_end_greather_than_begin + + def check_end_greather_than_begin + if self.begin and self.end and self.begin > self.end + errors.add(:end, :invalid) + end + end + + def self.from_range(index, range) + Period.new id: index, begin: range.begin, end: range.end + end + + def range + if self.begin and self.end and self.begin <= self.end + Range.new self.begin, self.end + end + end + + def intersect?(*other) + return false if range.nil? + + other = other.flatten + other = other.delete_if { |o| o.id == id } if id + + other.any? do |period| + if other_range = period.range + (range & other_range).present? + end + end + end + + def cover? date + range.cover? date + end + + # Stuff required for coocon + def new_record? + !persisted? + end + + def persisted? + id.present? + end + + def mark_for_destruction + self._destroy = true + end + + attribute :_destroy, type: Boolean + alias_method :marked_for_destruction?, :_destroy + end + + # Required by coocon + def build_period + Period.new + end + + def periods + @periods ||= init_periods + end + + def init_periods + if date_ranges + date_ranges.each_with_index.map { |r, index| Period.from_range(index, r) } + else + [] + end + end + private :init_periods + + validate :validate_periods + + def validate_periods + periods_are_valid = true + + unless periods.all?(&:valid?) + periods_are_valid = false + end + + periods.each do |period| + if period.intersect?(periods) + period.errors.add(:base, I18n.t('calendars.errors.overlapped_periods')) + periods_are_valid = false + end + end + + unless periods_are_valid + errors.add(:periods, :invalid) + end + end + + def periods_attributes=(attributes = {}) + @periods = [] + attributes.each do |index, period_attribute| + period = Period.new(period_attribute.merge(id: index)) + @periods << period unless period.marked_for_destruction? + end + + date_ranges_will_change! + end + + before_validation :fill_date_ranges + + def fill_date_ranges + if @periods + self.date_ranges = @periods.map(&:range).compact.sort_by(&:begin) + end + end + + after_save :clear_periods + + def clear_periods + @periods = nil + end + + private :clear_periods + +### dates + + class DateValue + include ActiveAttr::Model + + attribute :id, type: Integer + attribute :value, type: Date + + validates_presence_of :value + + def self.from_date(index, date) + DateValue.new id: index, value: date + end + + # Stuff required for coocon + def new_record? + !persisted? + end + + def persisted? + id.present? + end + + def mark_for_destruction + self._destroy = true + end + + attribute :_destroy, type: Boolean + alias_method :marked_for_destruction?, :_destroy + end + + # Required by coocon + def build_date_value + DateValue.new + end + + def date_values + @date_values ||= init_date_values + end + + def init_date_values + if dates + dates.each_with_index.map { |d, index| DateValue.from_date(index, d) } + else + [] + end + end + private :init_date_values + + validate :validate_date_values + + def validate_date_values + date_values_are_valid = true + + unless date_values.all?(&:valid?) + date_values_are_valid = false + end + + date_values.each do |date_value| + if date_values.count { |d| d.value == date_value.value } > 1 + date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_dates')) + date_values_are_valid = false + end + date_ranges.each do |date_range| + if date_range.cover? date_value.value + date_value.errors.add(:base, I18n.t('activerecord.errors.models.calendar.attributes.dates.date_in_date_ranges')) + date_values_are_valid = false + end + end + end + + unless date_values_are_valid + errors.add(:date_values, :invalid) + end + end + + def date_values_attributes=(attributes = {}) + @date_values = [] + attributes.each do |index, date_value_attribute| + date_value = DateValue.new(date_value_attribute.merge(id: index)) + @date_values << date_value unless date_value.marked_for_destruction? + end + + dates_will_change! + end + + before_validation :fill_dates + + def fill_dates + if @date_values + self.dates = @date_values.map(&:value).compact.sort + end + end + + after_save :clear_date_values + + def clear_date_values + @date_values = nil + end + + private :clear_date_values + +### + +end + +class Range + def intersection(other) + return nil if (self.max < other.begin or other.max < self.begin) + [self.begin, other.begin].max..[self.max, other.max].min + end + alias_method :&, :intersection +end diff --git a/app/models/chouette/area_type.rb b/app/models/chouette/area_type.rb deleted file mode 100644 index af614dc55..000000000 --- a/app/models/chouette/area_type.rb +++ /dev/null @@ -1,56 +0,0 @@ -class Chouette::AreaType < ActiveSupport::StringInquirer - - def initialize(text_code, numerical_code) - super text_code.to_s - @numerical_code = numerical_code - end - - def self.new(text_code, numerical_code = nil) - if text_code and numerical_code - super - elsif self === text_code - text_code - else - if Fixnum === text_code - text_code, numerical_code = definitions.rassoc(text_code) - else - text_code, numerical_code = definitions.assoc(text_code.to_s) - end - - super text_code, numerical_code - end - end - - def to_i - @numerical_code - end - - def inspect - "#{to_s}/#{to_i}" - end - - def name - if (to_s == 'itl') - to_s.upcase - else - camelize - end - end - - @@definitions = [ - ["boarding_position", 0], - ["quay", 1], - ["commercial_stop_point", 2], - ["stop_place", 3], - ["itl", 4] - ] - cattr_reader :definitions - - @@all = nil - def self.all - @@all ||= definitions.collect do |text_code, numerical_code| - new(text_code, numerical_code) - end - end - -end diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 9b2b2a9da..75e1a4a14 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -7,6 +7,7 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord has_many :vehicle_journeys, :dependent => :destroy has_many :vehicle_journey_at_stops, :through => :vehicle_journeys has_and_belongs_to_many :stop_points, -> { order("stop_points.position") }, :before_add => :vjas_add, :before_remove => :vjas_remove, :after_add => :shortcuts_update_for_add, :after_remove => :shortcuts_update_for_remove + has_many :stop_areas, through: :stop_points has_many :journey_pattern_sections has_many :route_sections, through: :journey_pattern_sections, dependent: :destroy diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index 3f7a72021..6c5d8501f 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -23,6 +23,8 @@ class Chouette::Line < Chouette::ActiveRecord has_many :footnotes, :inverse_of => :line, :validate => :true, :dependent => :destroy accepts_nested_attributes_for :footnotes, :reject_if => :all_blank, :allow_destroy => true + has_many :routing_constraint_zones + attr_reader :group_of_line_tokens # validates_presence_of :network diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb new file mode 100644 index 000000000..681069416 --- /dev/null +++ b/app/models/chouette/routing_constraint_zone.rb @@ -0,0 +1,9 @@ +class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord + belongs_to :line + has_array_of :stop_areas, class_name: 'Chouette::StopArea' + + validates_presence_of :name, :stop_area_ids, :line_id + validates :stop_areas, length: { minimum: 2 } + + self.primary_key = 'id' +end diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb index db240652e..cba43b3ff 100644 --- a/app/models/chouette/stop_area.rb +++ b/app/models/chouette/stop_area.rb @@ -7,6 +7,10 @@ class Chouette::StopArea < Chouette::ActiveRecord include Geokit::Mappable include ProjectionFields include StopAreaRestrictions + + extend Enumerize + enumerize :area_type, in: %i(zdep zder zdlp zdlr lda) + def self.model_name ActiveModel::Name.new self, Chouette, self.name.demodulize end @@ -105,7 +109,6 @@ class Chouette::StopArea < Chouette::ActiveRecord when "Quay" then [] when "CommercialStopPoint" then Chouette::StopArea.where(:area_type => ['Quay', 'BoardingPosition']) - [self] when "StopPlace" then Chouette::StopArea.where(:area_type => ['StopPlace', 'CommercialStopPoint']) - [self] - when "ITL" then Chouette::StopArea.where(:area_type => ['Quay', 'BoardingPosition', 'StopPlace', 'CommercialStopPoint']) end end @@ -143,9 +146,6 @@ class Chouette::StopArea < Chouette::ActiveRecord where :area_type => [ "BoardingPosition", "Quay" ] end - def self.itl - where :area_type => "ITL" - end def to_lat_lng Geokit::LatLng.new(latitude, longitude) if latitude and longitude @@ -206,21 +206,11 @@ class Chouette::StopArea < Chouette::ActiveRecord end def stop_area_type - area_type && Chouette::AreaType.new(area_type.underscore) + area_type ? area_type : " " end def stop_area_type=(stop_area_type) self.area_type = (stop_area_type ? stop_area_type.camelcase : nil) - if self.area_type == 'Itl' - self.area_type = 'ITL' - end - end - - @@stop_area_types = nil - def self.stop_area_types - @@stop_area_types ||= Chouette::AreaType.all.select do |stop_area_type| - stop_area_type.to_i >= 0 - end end def children_ids=(children_ids) diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index abe6186a7..7afdc4529 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -17,6 +17,8 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord has_many :dates, -> {order(:date)}, inverse_of: :time_table, :validate => :true, :class_name => "Chouette::TimeTableDate", :dependent => :destroy has_many :periods, -> {order(:period_start)}, inverse_of: :time_table, :validate => :true, :class_name => "Chouette::TimeTablePeriod", :dependent => :destroy + belongs_to :calendar + after_save :save_shortcuts def self.object_id_key diff --git a/app/models/organisation.rb b/app/models/organisation.rb index af1042081..8547ce5e1 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -13,6 +13,7 @@ class Organisation < ActiveRecord::Base has_many :line_referentials, through: :line_referential_memberships has_many :workbenches + has_many :calendars validates_presence_of :name validates_uniqueness_of :code diff --git a/app/policies/calendar_policy.rb b/app/policies/calendar_policy.rb new file mode 100644 index 000000000..3b17679f1 --- /dev/null +++ b/app/policies/calendar_policy.rb @@ -0,0 +1,31 @@ +class CalendarPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def show? + organisation_match? || record.shared + end + + def new? ; modify? end + def create? ; new? end + + def edit? ; modify? end + def update? ; edit? end + + def destroy? ; modify? end + + def share? + user.organisation.name == 'STIF' # FIXME + end + + def modify? + organisation_match? + end + + def organisation_match? + user.organisation == record.organisation + end +end diff --git a/app/policies/line_policy.rb b/app/policies/line_policy.rb index 92310f042..9d1f55cf2 100644 --- a/app/policies/line_policy.rb +++ b/app/policies/line_policy.rb @@ -8,8 +8,9 @@ class LinePolicy < ApplicationPolicy def create? false end - def update? ; true end + def update? ; false end def new? ; create? end - def edit? ; true end + def edit? ; false end def destroy? ; create? end + def update_footnote?; true end end diff --git a/app/policies/referential_policy.rb b/app/policies/referential_policy.rb new file mode 100644 index 000000000..ddf5188a0 --- /dev/null +++ b/app/policies/referential_policy.rb @@ -0,0 +1,13 @@ +class ReferentialPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def update? + !record.archived? + end + + def edit? ; update? end +end diff --git a/app/policies/routing_constraint_zone_policy.rb b/app/policies/routing_constraint_zone_policy.rb new file mode 100644 index 000000000..c6caf4ec5 --- /dev/null +++ b/app/policies/routing_constraint_zone_policy.rb @@ -0,0 +1,13 @@ +class RoutingConstraintZonePolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def create? ; true end + def update? ; true end + def new? ; true end + def edit? ; true end + def destroy? ; true end +end diff --git a/app/views/api/v1/routes/short_description.rabl b/app/views/api/v1/routes/short_description.rabl index ae149167d..900096ac5 100644 --- a/app/views/api/v1/routes/short_description.rabl +++ b/app/views/api/v1/routes/short_description.rabl @@ -5,3 +5,10 @@ extends "api/v1/trident_objects/short_description" attributes attr, :unless => lambda { |m| m.send( attr).nil?} end +child :stop_points => :stop_points do |stop_points| + node do |stop_point| + partial("api/v1/stop_areas/short_description", :object => stop_point.stop_area).merge(position: stop_point.position) + end +end + + diff --git a/app/views/api/v1/stop_areas/short_description.rabl b/app/views/api/v1/stop_areas/short_description.rabl index 73627c5a1..fb0213510 100644 --- a/app/views/api/v1/stop_areas/short_description.rabl +++ b/app/views/api/v1/stop_areas/short_description.rabl @@ -1,10 +1,10 @@ object @stop_area -extends "api/v1/trident_objects/short_description" +extends "api/v1/trident_objects/short_description" -[ :name, :area_type, :longitude, :latitude, :long_lat_type].each do |attr| +[ :id, :name, :area_type, :longitude, :latitude, :long_lat_type].each do |attr| attributes attr, :unless => lambda { |m| m.send( attr).nil?} end node(:parent_object_id) do |stop_area| - stop_area.parent.objectid + stop_area.parent.objectid end unless root_object.parent.nil? diff --git a/app/views/calendars/_calendars.html.slim b/app/views/calendars/_calendars.html.slim new file mode 100644 index 000000000..e91e9c530 --- /dev/null +++ b/app/views/calendars/_calendars.html.slim @@ -0,0 +1,12 @@ +- if @calendars.any? + = table_builder @calendars, + { @calendars.human_attribute_name(:name) => 'name', @calendars.human_attribute_name(:short_name) => 'short_name', @calendars.human_attribute_name(:shared) => 'shared' }, + [:show, :edit, :delete], + 'table table-bordered' + + .text-center + = will_paginate @calendars, container: false, renderer: RemoteBootstrapPaginationLinkRenderer + +- else + = replacement_msg t('.search_no_results') + diff --git a/app/views/calendars/_date_value_fields.html.slim b/app/views/calendars/_date_value_fields.html.slim new file mode 100644 index 000000000..3a9cdb7bd --- /dev/null +++ b/app/views/calendars/_date_value_fields.html.slim @@ -0,0 +1,14 @@ +.nested-fields + - if f.object.errors.has_key? :base + .row + .col-lg-12 + .alert.alert-danger + - f.object.errors[:base].each do |message| + p.small = message + .row + .col-xs-3 + = f.input :value, as: :date, html5: true, label: t('simple_form.labels.calendar.date_value') + .col-xs-1.end.text-right#delete-btn + = link_to_remove_association f, class: 'btn btn-danger', data: { confirm: t('are_you_sure') } do + span.fa.fa-trash + diff --git a/app/views/calendars/_form.html.slim b/app/views/calendars/_form.html.slim new file mode 100644 index 000000000..a97c16565 --- /dev/null +++ b/app/views/calendars/_form.html.slim @@ -0,0 +1,27 @@ +#calendar_form + .row + .col-xs-8.col-xs-offset-2 + = simple_form_for @calendar, html: { class: 'form-horizontal' } do |f| + = f.input :name + = f.input :short_name + .form-group + = f.label :dates + .well + = f.simple_fields_for :date_values do |date_value| + = render 'date_value_fields', f: date_value + .links + = link_to_add_association t('simple_form.labels.calendar.add_a_date'), f, :date_values, class: 'btn btn-primary btn-xs' + .form-group + = f.label :date_ranges + .well + = f.simple_fields_for :periods do |period| + = render 'period_fields', f: period + .links + = link_to_add_association t('simple_form.labels.calendar.add_a_date_range'), f, :periods, class: 'btn btn-primary btn-xs' + - if policy(@calendar).share? + = f.input :shared + .form-actions + = f.button :submit, as: :button, class: 'btn btn-info' + = link_to t('cancel'), calendars_path, class: 'btn btn-default' + + diff --git a/app/views/calendars/_period_fields.html.slim b/app/views/calendars/_period_fields.html.slim new file mode 100644 index 000000000..024d09de2 --- /dev/null +++ b/app/views/calendars/_period_fields.html.slim @@ -0,0 +1,16 @@ +.nested-fields + - if f.object.errors.has_key? :base + .row + .col-lg-12 + .alert.alert-danger + - f.object.errors[:base].each do |message| + p.small = message + .row + .col-xs-4 + = f.input :begin, as: :date, html5: true, label: t('simple_form.labels.calendar.ranges.begin') + .col-xs-3 + = f.input :end, as: :date, html5: true, label: t('simple_form.labels.calendar.ranges.end') + .col-xs-1.text-right#delete-btn + = link_to_remove_association f, class: 'btn btn-danger', data: { confirm: t('are_you_sure') } do + span.fa.fa-trash + diff --git a/app/views/calendars/edit.html.slim b/app/views/calendars/edit.html.slim new file mode 100644 index 000000000..22645cf24 --- /dev/null +++ b/app/views/calendars/edit.html.slim @@ -0,0 +1,3 @@ += title_tag t('.title', calendar: @calendar.name) + += render 'form' diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim new file mode 100644 index 000000000..41cd3d70c --- /dev/null +++ b/app/views/calendars/index.html.slim @@ -0,0 +1,29 @@ += title_tag t('.title') + +#calendar_search_form + = search_form_for @q, url: calendars_path, remote: true, html: { method: :get, class: 'form', id: 'search', role: 'form' } do |f| + .panel.panel-default + .panel-heading + .row + .col-md-3 + = f.label Calendar.human_attribute_name(:short_name) + = f.search_field :short_name_cont, class: 'form-control' + .col-md-3 + = f.label Calendar.human_attribute_name(:shared) + = f.select :shared_eq, [[t('.shared'), true], [t('.not_shared'), false]], { include_blank: '' }, { class: 'form-control', style: 'width: 100%', 'data-select2ed': 'true', 'data-select2ed-placeholder': t('.all') } + .col-md-3 + = f.label Calendar.human_attribute_name(:date) + = f.date_field :contains_date, class: 'form-control' + + .col-md-3 + button.btn.btn-primary#search-btn type='submit' + span.fa.fa-search + +#calendars + = render 'calendars' + +- content_for :sidebar do + ul.actions + li + = link_to t('calendars.actions.new'), new_calendar_path, class: 'add' + br diff --git a/app/views/calendars/index.js.slim b/app/views/calendars/index.js.slim new file mode 100644 index 000000000..936f93e5e --- /dev/null +++ b/app/views/calendars/index.js.slim @@ -0,0 +1 @@ +| $('#calendars').html("#{escape_javascript(render('calendars'))}"); diff --git a/app/views/calendars/new.html.slim b/app/views/calendars/new.html.slim new file mode 100644 index 000000000..f827e2eb6 --- /dev/null +++ b/app/views/calendars/new.html.slim @@ -0,0 +1,3 @@ += title_tag t('.title') + += render 'form' diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim new file mode 100644 index 000000000..c0671fa94 --- /dev/null +++ b/app/views/calendars/show.html.slim @@ -0,0 +1,46 @@ += title_tag t('.title', calendar: @calendar.name) + +p + label => "#{Calendar.human_attribute_name('name')} : " + = @calendar.name +p + label => "#{Calendar.human_attribute_name('short_name')} : " + = @calendar.short_name + +.row + .col-xs-4 + p + label => "#{Calendar.human_attribute_name('dates')} : " + table.table.table-condensed + tbody + - @calendar.dates.each do |date| + tr + td= l date + p + label => "#{Calendar.human_attribute_name('date_ranges')} : " + table.table.table-condensed + thead + th= t('simple_form.labels.calendar.ranges.begin') + th= t('simple_form.labels.calendar.ranges.end') + tbody + - @calendar.date_ranges.each do |date_range| + tr + td= l date_range.begin + td= l date_range.end + +p + label => "#{Calendar.human_attribute_name('shared')} : " + = @calendar.shared +p + label => "#{Organisation.model_name.human} : " + = @calendar.organisation.name + + +- content_for(:sidebar) do + ul.actions + - if policy(@calendar).edit? + li + = link_to t('calendars.actions.edit'), edit_calendar_path(@calendar), class: 'edit' + - if policy(@calendar).destroy? + li + = link_to t('calendars.actions.destroy'), calendar_path(@calendar), method: :delete, data: { confirm: t('calendars.actions.destroy_confirm') }, class: 'remove' diff --git a/app/views/companies/_companies.html.slim b/app/views/companies/_companies.html.slim index 4f89e8ede..a397bf06f 100644 --- a/app/views/companies/_companies.html.slim +++ b/app/views/companies/_companies.html.slim @@ -1,12 +1,11 @@ -/ .page_info -/ span.search = t('will_paginate.page_entries_info.search') -/ = page_entries_info @companies +- if @companies.any? + = table_builder @companies, + { 'Oid' => Proc.new { |n| n.try(:objectid).try(:local_id) }, @companies.human_attribute_name(:name) => 'name', @companies.human_attribute_name(:code) => 'code' }, + [:show, :edit, :delete], + 'table table-bordered' -.companies.paginated_content style="margin-top:20px;" - = table_builder @decoratedcompanies, - [:name, :edited_at, :published_at, :validity_period, :linecount, :transporter, :status], - ["show", "delete"], - 'table table-bordered' + .text-center + = will_paginate @companies, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @companies, container: false, renderer: RemoteBootstrapPaginationLinkRenderer +- else + = replacement_msg t('companies.search_no_results') diff --git a/app/views/companies/index.html.slim b/app/views/companies/index.html.slim index 15cd6398f..dad8f39f2 100644 --- a/app/views/companies/index.html.slim +++ b/app/views/companies/index.html.slim @@ -1,16 +1,18 @@ = title_tag t('companies.index.title') = search_form_for @q, url: line_referential_companies_path(@line_referential), remote: true, html: { method: :get, class: 'form', id: 'search', role: "form"} do |f| - .well.well-sm - .input-group - = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' - - .input-group-btn - button.btn.btn-primary type="submit" - span.fa.fa-search + + .panel.panel-default + .panel-heading + .input-group.col-md-12 + = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' + + .input-group-btn + button.btn.btn-primary#search-btn type="submit" + span.fa.fa-search #companies - = render partial: 'companies' + = render partial: 'companies', object: @companies - content_for :sidebar do ul.actions diff --git a/app/views/companies/new.html.slim b/app/views/companies/new.html.slim index 1acb1786f..68c0f76c3 100644 --- a/app/views/companies/new.html.slim +++ b/app/views/companies/new.html.slim @@ -1,2 +1,2 @@ = title_tag t('companies.new.title') -= render 'form'
\ No newline at end of file += render 'form' diff --git a/app/views/compliance_check_tasks/new.html.erb b/app/views/compliance_check_tasks/new.html.erb new file mode 100644 index 000000000..3f43a7dd7 --- /dev/null +++ b/app/views/compliance_check_tasks/new.html.erb @@ -0,0 +1,39 @@ +<%= title_tag t(".title") %> + +<%= semantic_form_for [@referential, @compliance_check_task], :url => referential_compliance_check_tasks_path(@referential) do |form| %> + <%= form.inputs do %> + <%= form.input :user_name, :as => :hidden, :input_html => { :value => current_user.name } %> <%= form.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } %> + <%= form.input :referential_id, :as => :hidden, :input_html => { :value => @referential.id } %> + <%= form.input :name %> + <%= form.input :rule_parameter_set_id, :as => :select, + :collection => @referential.organisation.rule_parameter_sets.map { |rps| [ rps.name, rps.id ] }, :include_blank => false %> + <%= form.input :references_type, :as => :select, :include_blank => t(".all") %> + <% @compliance_check_task.class.references_types.each do |type| %> + <%= form.input :reference_ids, :as => :reference_ids, :json => references_referential_compliance_check_tasks_path(@referential, :format => :json) + "?filter=#{type}", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :id => "#{type}_reference_ids", :input_html => { :id => "#{type}_reference_ids" }, :wrapper_html => { :style => "display:none;", :id => "#{type}", :"data-type" => "#{type}" } %> + <% end %> + <% end %> + + <%= form.actions do %> + <%= form.action :submit, :as => :button , :label => t( 'formtastic.validate' ) %> + <%= form.action :cancel, :as => :link %> + <% end %> +<% end %> + +<!-- = title_tag t('.title') + += semantic_form_for [@referential, @compliance_check_task], :url => referential_compliance_check_tasks_path(@referential) do |form| + = form.inputs do + = form.input :user_name, :as => :hidden, :input_html => { :value => current_user.name } + = form.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } + = form.input :referential_id, :as => :hidden, :input_html => { :value => @referential.id } + = form.input :name + = form.input :rule_parameter_set_id, :as => :select, + :collection => @referential.organisation.rule_parameter_sets.map { |rps| [ rps.name, rps.id ] }, :include_blank => false + = form.input :references_type, :as => :select, :include_blank => t(".all") + - @compliance_check_task.class.references_types.each do |type| + + = form.input :reference_ids, as: :reference_ids, json: references_referential_compliance_check_tasks_path(@referential, format: :json) + "?filter=#{type}", hint_text: t('search_hint'), no_result_text: t('no_result_text'), searching_text: t('searching_term'), id: "#{type}_reference_ids", input_html: { :id => "#{type}_reference_ids" }, wrapper_html: { :style => "display:none;", :id => "#{type}", :"data-type" => "#{type}" } + + = form.actions do + = form.action :submit, as: :button, label: t('formtastic.validate') + = form.action :cancel, as: :link --> diff --git a/app/views/compliance_check_tasks/new.html.slim b/app/views/compliance_check_tasks/new.html.slim deleted file mode 100644 index 212e7f618..000000000 --- a/app/views/compliance_check_tasks/new.html.slim +++ /dev/null @@ -1,17 +0,0 @@ -= title_tag t('.title') - -= semantic_form_for [@referential, @compliance_check_task], :url => referential_compliance_check_tasks_path(@referential) do |form| - = form.inputs do - = form.input :user_name, :as => :hidden, :input_html => { :value => current_user.name } %> <%= form.input :user_id, :as => :hidden, :input_html => { :value => current_user.id } - = form.input :referential_id, :as => :hidden, :input_html => { :value => @referential.id } - = form.input :name - = form.input :rule_parameter_set_id, :as => :select, - :collection => @referential.organisation.rule_parameter_sets.map { |rps| [ rps.name, rps.id ] }, :include_blank => false - = form.input :references_type, :as => :select, :include_blank => t(".all") - - @compliance_check_task.class.references_types.each do |type| - - = form.input :reference_ids, as: :reference_ids, json: references_referential_compliance_check_tasks_path(@referential, format: :json) + "?filter=#{type}", hint_text: t('search_hint'), no_result_text: t('no_result_text'), searching_text: t('searching_term'), id: "#{type}_reference_ids", input_html: { :id => "#{type}_reference_ids" }, wrapper_html: { :style => "display:none;", :id => "#{type}", :"data-type" => "#{type}" } - - = form.actions do - = form.action :submit, as: :button, label: t('formtastic.validate') - = form.action :cancel, as: :link
\ No newline at end of file diff --git a/app/views/compliance_check_tasks/new.js.coffee b/app/views/compliance_check_tasks/new.js.coffee index d7066b6f7..ba62f53b2 100644 --- a/app/views/compliance_check_tasks/new.js.coffee +++ b/app/views/compliance_check_tasks/new.js.coffee @@ -1,7 +1,7 @@ jQuery -> - # <% ComplianceCheckTask.references_types.map { |type| type_ids_model_references_type( ComplianceCheckTask, type)}.each do |rt| %> - # $("textarea.<%= rt.input_class %>").tokenInput('<%= references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, :format => :json) %>', { prePopulate: $('#').data('pre'), minChars: 1, hintText: '<%= t('search_hint') %>', noResultsText: '<%= t('no_result_text') %>', searchingText: '<%= t('searching_term') %>'}); - # <% end %> + <% ComplianceCheckTask.references_types.map { |type| type_ids_model_references_type( ComplianceCheckTask, type)}.each do |rt| %> + $("textarea.<%= rt.input_class %>").tokenInput('<%= references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, :format => :json) %>', { prePopulate: $('#').data('pre'), minChars: 1, hintText: '<%= t('search_hint') %>', noResultsText: '<%= t('no_result_text') %>', searchingText: '<%= t('searching_term') %>'}); + <% end %> - - ComplianceCheckTask.references_types.map { |type| type_ids_model_references_type( ComplianceCheckTask, type)}.each do |rt| - $("textarea.#{rt.input_class}").tokenInput("#{references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, format: :json)}", { prePopulate: $('#').data('pre'), minChars: 1, hintText: "#{t('search_hint')}", noResultsText: "#{t('no_result_text')}", searchingText: "#{t('searching_term')}"}); + # - ComplianceCheckTask.references_types.map { |type| type_ids_model_references_type( ComplianceCheckTask, type)}.each do |rt| + # $("textarea.#{rt.input_class}").tokenInput("#{references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, format: :json)}", { prePopulate: $('#').data('pre'), minChars: 1, hintText: "#{t('search_hint')}", noResultsText: "#{t('no_result_text')}", searchingText: "#{t('searching_term')}"}); diff --git a/app/views/compliance_checks/_compliance_check.html.slim b/app/views/compliance_checks/_compliance_check.html.slim index db4753563..383a7ea82 100644 --- a/app/views/compliance_checks/_compliance_check.html.slim +++ b/app/views/compliance_checks/_compliance_check.html.slim @@ -10,8 +10,8 @@ .panel-body p - = link_to font_awesome_classic_tag("fa-external-link") + t("compliance_checks.actions.report"), report_referential_compliance_check_path(@referential, compliance_check.id)) if compliance_check.report? + = link_to( font_awesome_classic_tag("fa-external-link") + t("compliance_checks.actions.report"), report_referential_compliance_check_path(@referential, compliance_check.id)) if compliance_check.report? .panel-footer .history = l compliance_check.created_at, :format => "%d/%m/%Y %H:%M" - = " | #{compliance_check.user_name}"
\ No newline at end of file + = " | #{compliance_check.user_name}" diff --git a/app/views/compliance_checks/_compliance_check_results.html.slim b/app/views/compliance_checks/_compliance_check_results.html.slim index e2b8cb6f4..8e86c174e 100644 --- a/app/views/compliance_checks/_compliance_check_results.html.slim +++ b/app/views/compliance_checks/_compliance_check_results.html.slim @@ -25,7 +25,7 @@ p = t('compliance_check_result.statuses.uncheck') -table.table.table-hover.toggle-circle.toggle-medium data-filter="#filter" data-page-size="20" data-title-nok="#{t('compliance_check_result.statuses.nok')}" data-title-uncheck="#{t('compliance_check_result.statuses.uncheck')}" data-title-ok="#{t('compliance_check_result.statuses.ok')} +table.table.table-hover.toggle-circle.toggle-medium data-filter="#filter" data-page-size="20" data-title-nok="#{t('compliance_check_result.statuses.nok')}" data-title-uncheck="#{t('compliance_check_result.statuses.uncheck')}" data-title-ok="#{t('compliance_check_result.statuses.ok')}" thead tr th data-sort-ignore="true" @@ -89,4 +89,4 @@ table.table.table-hover.toggle-circle.toggle-medium data-filter="#filter" data-p tfoot.hide-if-no-paging tr td colspan="5" - ul.pagination.pagination-centered
\ No newline at end of file + ul.pagination.pagination-centered diff --git a/app/views/group_of_lines/index.html.slim b/app/views/group_of_lines/index.html.slim index a684095f0..69b1cd0d6 100644 --- a/app/views/group_of_lines/index.html.slim +++ b/app/views/group_of_lines/index.html.slim @@ -6,7 +6,7 @@ .input-group.col-md-12 = f.text_field :name_cont, :placeholder => "#{t('.name')}", class: 'form-control' .input-group-btn - button.btn.btn-default type="submit" + button.btn.btn-default#search-btn type="submit" i.fa.fa-search / <!-- /input-group --> diff --git a/app/views/journey_patterns_collections/show.html.slim b/app/views/journey_patterns_collections/show.html.slim new file mode 100644 index 000000000..7b6f7ae7a --- /dev/null +++ b/app/views/journey_patterns_collections/show.html.slim @@ -0,0 +1,4 @@ +#journey_patterns += javascript_tag do + | window.journeyPatternLength = #{@journey_patterns.total_entries()} += javascript_include_tag 'es6_browserified/journey_patterns/index.js' diff --git a/app/views/journey_patterns_collections/show.rabl b/app/views/journey_patterns_collections/show.rabl new file mode 100644 index 000000000..c241a9c0e --- /dev/null +++ b/app/views/journey_patterns_collections/show.rabl @@ -0,0 +1,3 @@ +collection @journey_patterns +extends "api/v1/journey_patterns/show" + diff --git a/app/views/journey_patterns_collections/update.rabl b/app/views/journey_patterns_collections/update.rabl new file mode 100644 index 000000000..13ced5655 --- /dev/null +++ b/app/views/journey_patterns_collections/update.rabl @@ -0,0 +1,2 @@ +collection @journey_patterns +extends "api/v1/journey_patterns/show" diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index fad7a3ed7..c3f0975d2 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -17,11 +17,9 @@ html lang=I18n.locale = javascript_include_tag "http://maps.google.com/maps/api/js?v=3.2&sensor=false" = javascript_include_tag "http://openlayers.org/api/OpenLayers.js" - / Todo from @jpl: check if it works... - <script type="text/JavaScript"> - OpenLayers.ImgPath = polymorphic_path_patch('/assets/openlayers/') - </script> - + = javascript_tag do + | OpenLayers.ImgPath = "#{polymorphic_path_patch('/assets/openlayers/')}" + = analytics_init if Rails.env.production? = csrf_meta_tag diff --git a/app/views/layouts/application_new.html.slim b/app/views/layouts/application_new.html.slim new file mode 100644 index 000000000..6effdc432 --- /dev/null +++ b/app/views/layouts/application_new.html.slim @@ -0,0 +1,33 @@ +doctype html +html lang=I18n.locale + head + meta charset="utf-8" + meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" + + = csrf_meta_tag + + title STIF BOIV + + = stylesheet_link_tag 'base', media: 'all', 'data-turbolinks-track': true + = stylesheet_link_tag 'application_new', media: 'all', 'data-turbolinks-track': true + + = javascript_include_tag 'application', 'data-turbolinks-track': true + + + body + = render 'layouts/new/main_nav' + = render 'layouts/new/widget_bar' + + .container-fluid + = render partial: 'layouts/new/flash_messages', flash: flash + + .row + .col-lg-12.col-md-12.col-sm-12.col-xs-12 + .container + .row + .col-lg-12.col-md-12.col-sm-12.col-xs-12 + #workspace class=("#{controller_name} #{action_name}") + = yield + + #sidebar + = yield :sidebar diff --git a/app/views/layouts/new/_breadcrumb.html.slim b/app/views/layouts/new/_breadcrumb.html.slim new file mode 100644 index 000000000..a101098fe --- /dev/null +++ b/app/views/layouts/new/_breadcrumb.html.slim @@ -0,0 +1,2 @@ +- if @breadcrumbs.present? + = render_breadcrumbs builder: BootstrapBreadcrumbsBuilder, tag: :li, separator: '' diff --git a/app/views/layouts/new/_flash_messages.html.slim b/app/views/layouts/new/_flash_messages.html.slim new file mode 100644 index 000000000..70076d42e --- /dev/null +++ b/app/views/layouts/new/_flash_messages.html.slim @@ -0,0 +1,18 @@ +.row + .col-lg-12 + - flash.each do |name, msg| + - if msg.is_a?(String) + - if name == 'notice' + .notice.alert class="alert-success" role="alert" + = content_tag :span, msg + + - if name == 'error' || name == 'alert' + .notice.alert class="alert-danger" role="alert" + = content_tag :span, msg + +/ - flash.each do |type, message| +/ div class="alert #{bootstrap_class_for(type)} fade in" role="alert" +/ button.close data-dismiss="alert" +/ |x +/ +/ = flash_message_for type, message diff --git a/app/views/layouts/new/_main_nav.html.slim b/app/views/layouts/new/_main_nav.html.slim new file mode 100644 index 000000000..51ee0e84e --- /dev/null +++ b/app/views/layouts/new/_main_nav.html.slim @@ -0,0 +1,47 @@ +nav#main_nav + .nav-menu + span.toggleMenu title='Toggle menu' + + ul.menu-content + li.brand + span.brandname Stif BOIV + + li + = link_to '#', class: 'mc-item' do + span.mci-icon + span.fa.fa-lg.fa-paw + span.mci-desc + h4 = "Espace de données" + em.small + = "Accès à mes offres de transport" + br + = "Détail des opérations en cours" + li + = link_to '#', class: 'mc-item' do + span.mci-icon + span.fa.fa-lg.fa-paw + span.mci-desc + h4 = "Organisation" + em.small = "Consulter mon profil et la liste des membres de mon organisation" + + li + = link_to '#', class: 'mc-item' do + span.mci-icon + span.fa.fa-lg.fa-paw + span.mci-desc + h4 = "Portail" + + div + = render 'layouts/new/breadcrumb' + + ul.nav-right + li + = link_to '#', title: 'Mon compte' do + span.fa.fa-lg.fa-user + + li + = link_to '#', title: 'Rechercher' do + span.fa.fa-lg.fa-search + li + = link_to '#', title: 'Notifications' do + span.fa.fa-lg.fa-bell-o diff --git a/app/views/layouts/new/_widget_bar.html.slim b/app/views/layouts/new/_widget_bar.html.slim new file mode 100644 index 000000000..8de50722f --- /dev/null +++ b/app/views/layouts/new/_widget_bar.html.slim @@ -0,0 +1,36 @@ +#widget_bar + .toggleWidgets title='Toggle widget bar' + + #widgets.panel-group.widget-list + .panel.panel-default + .panel-heading + h4.panel-title + = link_to '#widgetOne', data: { toggle: 'collapse', parent: '#widgets' }, 'aria-expanded' => 'true' do + |Item #1 + + #widgetOne.panel-collapse.collapse.in + .panel-body + p + |Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + + .panel.panel-default + .panel-heading + h4.panel-title + = link_to '#widgetTwo', data: { toggle: 'collapse', parent: '#widgets' }, 'aria-expanded' => 'false' do + |Item #2 + + #widgetTwo.panel-collapse.collapse + .panel-body + p + |Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + + .panel.panel-default + .panel-heading + h4.panel-title + = link_to '#widgetThree', data: { toggle: 'collapse', parent: '#widgets' }, 'aria-expanded' => 'false' do + |Item #3 + + #widgetThree.panel-collapse.collapse + .panel-body + p + |Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/app/views/line_footnotes/_form.html.slim b/app/views/line_footnotes/_form.html.slim new file mode 100644 index 000000000..9eb4e1a70 --- /dev/null +++ b/app/views/line_footnotes/_form.html.slim @@ -0,0 +1,15 @@ += semantic_form_for [@referential, @line], url: referential_line_footnotes_path do |form| + = form.inputs do + .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' + + = form.actions do + = form.action :submit, as: :button + = form.action :cancel, as: :link diff --git a/app/views/line_footnotes/edit.html.slim b/app/views/line_footnotes/edit.html.slim new file mode 100644 index 000000000..f09d99e6d --- /dev/null +++ b/app/views/line_footnotes/edit.html.slim @@ -0,0 +1,3 @@ += title_tag t('lines.edit.title', line: @line.name) + += render 'form' diff --git a/app/views/line_footnotes/show.html.slim b/app/views/line_footnotes/show.html.slim new file mode 100644 index 000000000..e8d3c459f --- /dev/null +++ b/app/views/line_footnotes/show.html.slim @@ -0,0 +1,15 @@ +h2 + = t('lines.show.title', line: @line.name) +.line_show + p + label = "#{@line.human_attribute_name('footnotes')} : " + ul + - @line.footnotes.each do |footnote| + li = "#{footnote.code} : #{footnote.label}" + + +- content_for :sidebar do + ul.actions + - if policy(@line).update_footnote? + li + = link_to t('lines.actions.edit_footnotes'), edit_referential_line_footnotes_path(@referential, @line), class: 'edit' diff --git a/app/views/lines/_lines.html.slim b/app/views/lines/_lines.html.slim index 638fdfb6d..a9f0f4a14 100644 --- a/app/views/lines/_lines.html.slim +++ b/app/views/lines/_lines.html.slim @@ -1,9 +1,12 @@ -.page_info - span.search = t("will_paginate.page_entries_info.search") - = page_entries_info @lines +- if @lines.any? + = table_builder @lines, + { 'Oid' => Proc.new { |n| n.objectid.local_id }, @lines.human_attribute_name(:id) => 'id', + @lines.human_attribute_name(:number) => 'number', @lines.human_attribute_name(:name) => 'name', @lines.human_attribute_name(:network) => Proc.new { |n| n.try(:network).try(:name) }, @lines.human_attribute_name(:company) => Proc.new { |n| n.try(:company).try(:name) } }, + [:show], + 'table table-bordered' -.lines.paginated_content - = paginated_content(@lines) + .text-center + = will_paginate @lines, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @lines, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer +- else + = replacement_msg t('referential_lines.search_no_results') diff --git a/app/views/lines/show.html.slim b/app/views/lines/show.html.slim index d887d2181..7aeb78033 100644 --- a/app/views/lines/show.html.slim +++ b/app/views/lines/show.html.slim @@ -25,7 +25,6 @@ = t('lines.index.unset') - else = link_to @line.network.name, [@line_referential, @line.network] - p label = "#{@line.human_attribute_name(:company)} : " - if @line.company.nil? @@ -113,9 +112,9 @@ / label = "#{@line.human_attribute_name('comment')} : " / = @line.comment - / .row - / #mobility_restricted_suitability.col-md-6 - / #flexible_service.col-md-6 + / .row + / #mobility_restricted_suitability.col-md-6 + / #flexible_service.col-md-6 - content_for :sidebar do ul.actions @@ -130,9 +129,4 @@ li = link_to t('lines.actions.destroy'), line_referential_line_path(@line_referential, @line), method: :delete, :data => {:confirm => t('lines.actions.destroy_confirm')}, class: 'remove' - - if !@line.hub_restricted? || (@line.hub_restricted? && @line.routes.size < 2) - / FIXME #825 - li - / = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add' - = creation_tag(@line) diff --git a/app/views/networks/_network.html.slim b/app/views/networks/_network.html.slim deleted file mode 100644 index 94745ca3d..000000000 --- a/app/views/networks/_network.html.slim +++ /dev/null @@ -1,15 +0,0 @@ -#index_item.panel.panel-default.network - .panel-heading - .panel-title.clearfix - span.pull-right - - if policy(network).update? - = link_to edit_line_referential_network_path(@line_referential, network), class: 'btn btn-default btn-sm' do - span.fa.fa-pencil - - if policy(network).destroy? - = link_to line_referential_network_path(@line_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 [@line_referential, network], class: 'preview', title: "#{Chouette::Network.model_name.human.capitalize} #{network.name}" do - span.name - = truncate(network.name, :length => 20) diff --git a/app/views/networks/_networks.html.slim b/app/views/networks/_networks.html.slim index 9143e5c16..3075557e5 100644 --- a/app/views/networks/_networks.html.slim +++ b/app/views/networks/_networks.html.slim @@ -1,9 +1,43 @@ -.page_info - span.search = t('will_paginate.page_entries_info.search') - = page_entries_info @networks +- if @networks.any? + = table_builder @networks, + { 'Oid' => Proc.new { |n| n.try(:objectid).try(:local_id) }, @networks.human_attribute_name(:name) => 'name' }, + [:show, :edit, :delete], + 'table table-bordered' -.networks.paginated_content - = paginated_content(@networks) + .text-center + = will_paginate @networks, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @networks, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file +- else + = replacement_msg t('networks.search_no_results') + +/ .networks +/ table.table.table-bordered.table-hover +/ thead +/ tr +/ th = Chouette::Network.human_attribute_name(:name) +/ th.text-center = "Actions" +/ +/ tbody +/ - @networks.each do |network| +/ tr +/ td +/ span.label.label-default style='margin-right:5px' +/ = network.objectid.local_id +/ = network.name +/ +/ / Actions +/ td.text-center +/ .btn-group.btn-group-xs +/ .btn-primary.btn.dropdown-toggle data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" +/ span.fa.fa-bars +/ span.caret +/ +/ ul.dropdown-menu +/ li = link_to 'Voir', line_referential_network_path(@line_referential, network) +/ - if policy(network).update? +/ li = link_to 'Editer', edit_line_referential_network_path(@line_referential, network) +/ - if policy(network).destroy? +/ li = link_to 'Supprimer', line_referential_network_path(@line_referential, network), method: :delete, data: { confirm: t('networks.actions.destroy_confirm') } +/ +/ .text-center +/ = will_paginate @networks, container: false, renderer: RemoteBootstrapPaginationLinkRenderer diff --git a/app/views/networks/index.html.slim b/app/views/networks/index.html.slim index 3e3aeb032..0134f4c0d 100644 --- a/app/views/networks/index.html.slim +++ b/app/views/networks/index.html.slim @@ -1,16 +1,17 @@ = title_tag t('networks.index.title') = search_form_for @q, url: line_referential_networks_path(@line_referential), remote: true, html: {method: :get, class: "form", id: "search", role: "form"} do |f| - .well.well-sm - .input-group - = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' - - .input-group-btn - button.btn.btn-primary type="submit" - span.fa.fa-search + .panel.panel-default + .panel-heading + .input-group.col-md-12 + = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' + + .input-group-btn + button.btn.btn-primary#search-btn type="submit" + span.fa.fa-search #networks - = render 'networks' + = render partial: 'networks', object: @networks - content_for :sidebar do ul.actions diff --git a/app/views/referential_companies/_companies.html.slim b/app/views/referential_companies/_companies.html.slim index bcd471cc7..697131dcb 100644 --- a/app/views/referential_companies/_companies.html.slim +++ b/app/views/referential_companies/_companies.html.slim @@ -1,9 +1,11 @@ -.page_info - span.search = t('will_paginate.page_entries_info.search') - = page_entries_info(@companies) +- if @companies.any? + = table_builder @companies, + { 'Oid' => Proc.new { |n| n.try(:objectid).try(:local_id) }, Chouette::Company.human_attribute_name(:name) => 'name', Chouette::Company.human_attribute_name(:code) => 'code' }, + [:show, :edit, :delete], + 'table table-bordered' -.companies.paginated_content - = paginated_content(@companies) + .text-center + = will_paginate @companies, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @companies, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file +- else + = replacement_msg t('companies.search_no_results') diff --git a/app/views/referential_companies/_company.html.slim b/app/views/referential_companies/_company.html.slim deleted file mode 100644 index e6090540d..000000000 --- a/app/views/referential_companies/_company.html.slim +++ /dev/null @@ -1,18 +0,0 @@ -#index_item.company.panel.panel-default - .panel-heading - .panel-title.clearfix - span.pull-right - - 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 - = truncate(company.name, length: 20) - .panel-body - p - = company.human_attribute_name('code') - = company.code diff --git a/app/views/referential_companies/index.html.slim b/app/views/referential_companies/index.html.slim index 6af6d7fc8..d5d02fef2 100644 --- a/app/views/referential_companies/index.html.slim +++ b/app/views/referential_companies/index.html.slim @@ -5,15 +5,12 @@ .panel.panel-default .panel-heading .input-group.col-md-12 - = f.text_field :name_cont, placeholder: t('.name'), class: 'form-control' + = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' + .input-group-btn - button.btn.btn-default type="submit" - i.fa.fa-search + button.btn.btn-primary#search-btn type="submit" + span.fa.fa-search - / <!-- /input-group --> - / <!-- <a data-toggle="collapse" data-parent="#search" href="#advanced_search"> --> - / <!-- <i class="fa fa-plus"></i> <%= "#{t('.advanced_search')}" %> --> - / <!-- </a> --> #companies = render partial: 'companies', object: @companies diff --git a/app/views/referential_companies/index.js.slim b/app/views/referential_companies/index.js.slim index 3a1739abf..601e2bd08 100644 --- a/app/views/referential_companies/index.js.slim +++ b/app/views/referential_companies/index.js.slim @@ -1 +1 @@ -/ | $('#companies').html("= escape_javascript(render('companies'))"); +| $('#companies').html("#{escape_javascript(render('companies'))}"); diff --git a/app/views/referential_group_of_lines/index.html.slim b/app/views/referential_group_of_lines/index.html.slim index 5e3c2eb17..9fa3eb381 100644 --- a/app/views/referential_group_of_lines/index.html.slim +++ b/app/views/referential_group_of_lines/index.html.slim @@ -6,7 +6,7 @@ .input-group.col-md-12 = f.text_field :name_cont, :placeholder => "#{t('.name')}", class: 'form-control' .input-group-btn - button.btn.btn-default type="submit" + button.btn.btn-default#search-btn type="submit" i.fa.fa-search / <!-- /input-group --> @@ -21,4 +21,4 @@ ul.actions li = link_to t('group_of_lines.actions.new'), new_referential_group_of_line_path(@referential), class: 'add' - br
\ No newline at end of file + br diff --git a/app/views/referential_lines/_form.html.slim b/app/views/referential_lines/_form.html.slim index a4c98d43d..5e450d0cc 100644 --- a/app/views/referential_lines/_form.html.slim +++ b/app/views/referential_lines/_form.html.slim @@ -17,16 +17,6 @@ / = form.input :objectid, :required => !@line.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.line.objectid") } / = form.input :group_of_line_tokens, :label => t('.group_of_lines'), as: :text, :input_html => { :"data-pre" => ( @line.group_of_lines.map { |group_of_line| { :id => group_of_line.id, :name => group_of_line.name } } ).to_json } - .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' - = form.actions do = form.action :submit, as: :button = form.action :cancel, as: :link diff --git a/app/views/referential_lines/_lines.html.slim b/app/views/referential_lines/_lines.html.slim index fc89a8939..a9f0f4a14 100644 --- a/app/views/referential_lines/_lines.html.slim +++ b/app/views/referential_lines/_lines.html.slim @@ -1,9 +1,12 @@ -.page_info - span.search = t('will_paginate.page_entries_info.search') - = page_entries_info @lines +- if @lines.any? + = table_builder @lines, + { 'Oid' => Proc.new { |n| n.objectid.local_id }, @lines.human_attribute_name(:id) => 'id', + @lines.human_attribute_name(:number) => 'number', @lines.human_attribute_name(:name) => 'name', @lines.human_attribute_name(:network) => Proc.new { |n| n.try(:network).try(:name) }, @lines.human_attribute_name(:company) => Proc.new { |n| n.try(:company).try(:name) } }, + [:show], + 'table table-bordered' -.lines.paginated_content - = paginated_content(@lines) + .text-center + = will_paginate @lines, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @lines, container: false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file +- else + = replacement_msg t('referential_lines.search_no_results') diff --git a/app/views/referential_lines/index.html.slim b/app/views/referential_lines/index.html.slim index 9facb1a73..1da5b7e3a 100644 --- a/app/views/referential_lines/index.html.slim +++ b/app/views/referential_lines/index.html.slim @@ -13,7 +13,7 @@ - if policy(Chouette::Line).destroy? #multiple_selection_menu - h4> = t(".multi_selection") + h4 = t(".multi_selection") .disabled a.enable href="#" diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index e32978b20..ad455862d 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -108,14 +108,12 @@ h2 / = ": #{@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}" - + label = link_to @line.human_attribute_name('footnotes'), referential_line_footnotes_path(@referential, @line) / p / label = "#{@line.human_attribute_name('comment')} : " / = @line.comment + p + label = link_to Chouette::RoutingConstraintZone.model_name.human.pluralize(:fr), referential_line_routing_constraint_zones_path(@referential, @line) .row #mobility_restricted_suitability.col-md-6 diff --git a/app/views/referential_networks/_network.html.slim b/app/views/referential_networks/_network.html.slim deleted file mode 100644 index f7c7b66eb..000000000 --- a/app/views/referential_networks/_network.html.slim +++ /dev/null @@ -1,15 +0,0 @@ -#index_item.panel.panel-default.network - .panel-heading - .panel-title.clearfix - span.pull-right - - 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) diff --git a/app/views/referential_networks/_networks.html.slim b/app/views/referential_networks/_networks.html.slim index 9143e5c16..42f947f73 100644 --- a/app/views/referential_networks/_networks.html.slim +++ b/app/views/referential_networks/_networks.html.slim @@ -1,9 +1,11 @@ -.page_info - span.search = t('will_paginate.page_entries_info.search') - = page_entries_info @networks +- if @networks.any? + = table_builder @networks, + { 'Oid' => Proc.new { |n| n.try(:objectid).try(:local_id) }, Chouette::Network.human_attribute_name(:name) => 'name' }, + [:show, :edit, :delete], + 'table table-bordered' -.networks.paginated_content - = paginated_content(@networks) + .text-center + = will_paginate @networks, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @networks, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file +- else + = replacement_msg t('networks.search_no_results') diff --git a/app/views/referential_networks/index.html.slim b/app/views/referential_networks/index.html.slim index e3e9f2a07..781df4903 100644 --- a/app/views/referential_networks/index.html.slim +++ b/app/views/referential_networks/index.html.slim @@ -4,17 +4,14 @@ .panel.panel-default .panel-heading .input-group.col-md-12 - = f.text_field :name_cont, placeholder: "#{t('.name')}", class: 'form-control' - .input-group-btn - button.btn.btn-default type="submit" - i.fa.fa-search + = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' - / <!-- <a data-toggle="collapse" data-parent="#search" href="#advanced_search"> --> - / <!-- <i class="fa fa-plus"></i> <%= "#{t('.advanced_search')}" %> --> - / <!-- </a> --> + .input-group-btn + button.btn.btn-primary#search-btn type="submit" + span.fa.fa-search #networks - = render 'networks' + = render partial: 'networks', object: @networks - content_for :sidebar do ul.actions diff --git a/app/views/referential_networks/index.js.slim b/app/views/referential_networks/index.js.slim index 930880dfa..3302a0f2e 100644 --- a/app/views/referential_networks/index.js.slim +++ b/app/views/referential_networks/index.js.slim @@ -1 +1 @@ -| $('#networks').html("#{escape_javascript(render('networks'))}");
\ No newline at end of file +| $('#networks').html("#{escape_javascript(render('networks'))}"); diff --git a/app/views/referential_stop_areas/_form.html.slim b/app/views/referential_stop_areas/_form.html.slim index 5a27abcb5..50f5d4aaf 100644 --- a/app/views/referential_stop_areas/_form.html.slim +++ b/app/views/referential_stop_areas/_form.html.slim @@ -7,8 +7,8 @@ = form.inputs do = form.input :id, as: :hidden = form.input :name, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")} - = form.input :stop_area_type, as: :select, :input_html => { :disabled => !@stop_area.new_record? }, :collection => Chouette::StopArea.stop_area_types, :include_blank => false, :member_label => Proc.new { |stop_area_type| t("area_types.label.#{stop_area_type}") } - + = form.input :stop_area_type, as: :select, :input_html => { :disabled => !@stop_area.new_record? }, :collection => Chouette::StopArea.area_type.options, :include_blank => false } + .location_info h3 = t("stop_areas.stop_area.localisation") #prefetch @@ -26,7 +26,7 @@ .stop_areas.stop_area.general_info h3 = t("stop_areas.stop_area.general") - + = form.inputs do = form.input :objectid, :required => !@stop_area.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.objectid")} = form.input :registration_number, required: format_restriction_for_locales(@referential) == '.hub', :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.registration_number")} @@ -149,4 +149,4 @@ javascript: $('input[name="stop_area[city_name]"]').val(datum.city); }) - });
\ No newline at end of file + }); diff --git a/app/views/referential_stop_areas/_stop_areas.html.slim b/app/views/referential_stop_areas/_stop_areas.html.slim index e05bab1bc..f976eb327 100644 --- a/app/views/referential_stop_areas/_stop_areas.html.slim +++ b/app/views/referential_stop_areas/_stop_areas.html.slim @@ -1,9 +1,11 @@ -.page_info - span.search = t("will_paginate.page_entries_info.search") - = page_entries_info @stop_areas +- if @stop_areas.any? + = table_builder @stop_areas, + { 'Object_id' => 'objectid', @stop_areas.human_attribute_name(:name) => 'name', @stop_areas.human_attribute_name(:registration_number) => 'registration_number', @stop_areas.human_attribute_name(:city_name) => 'city_name', @stop_areas.human_attribute_name(:zip_code) => 'zip_code' }, + [:show, :edit, :delete], + 'table table-bordered' -.stop_areas.paginated_content - = paginated_content(@stop_areas) + .text-center + = will_paginate @stop_areas, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @stop_areas, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file +- else + = replacement_msg t('stop_areas.search_no_results') diff --git a/app/views/referential_stop_areas/index.html.slim b/app/views/referential_stop_areas/index.html.slim index 54a731de2..1cbe1945f 100644 --- a/app/views/referential_stop_areas/index.html.slim +++ b/app/views/referential_stop_areas/index.html.slim @@ -1,20 +1,17 @@ = title_tag t('stop_areas.index.title') -#country_codes - = @country_codes.to_json - = search_form_for @q, :url => referential_stop_areas_path(@referential), remote: true, :html => {:method => :get, class: "form-inline", :id => "search", role: "form"} do |f| .panel.panel-default .panel-heading .input-group.col-md-9.col-sm-9 = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' .input-group-btn - button.btn.btn-default type="submit" - i.fa.fa-search + button.btn.btn-primary#search-btn type="submit" + span.fa.fa-search a data-toggle="collapse" data-parent="#search" href="#advanced_search" - i.fa.fa-plus - = "#{t('.advanced_search')}" + span.fa.fa-plus + = " #{t('.advanced_search')}" #advanced_search.panel-collapse.collapse .panel-body @@ -22,9 +19,9 @@ .col-sm-3 = f.text_field :zip_code_cont, placeholder: "#{t('.zip_code')}", class: 'form-control typeahead', style: 'width: 100%' .col-sm-3 + = f.select(:area_type_cont, Chouette::StopArea.area_type.options, { include_blank: '' }, { class: 'form-control', style: 'width: 100%', 'data-select2ed': 'true', 'data-select2ed-placeholder': t(".area_type") }) = f.text_field :city_name_cont, placeholder: "#{t('.city_name')}", class: 'form-control typeahead', style: 'width: 100%' .col-sm-3 - = f.select(:area_type_cont, options_from_collection_for_select(Chouette::StopArea.stop_area_types, 'name', Proc.new { |stop_area_type| t("area_types.label.#{stop_area_type}") } ), { include_blank: '' }, { class: 'form-control', style: 'width: 100%', 'data-select2ed': 'true', 'data-select2ed-placeholder': t(".area_type") }) #stop_areas = render 'stop_areas' diff --git a/app/views/referentials/_form.html.slim b/app/views/referentials/_form.html.slim index c0999318a..5b0c0d3c3 100644 --- a/app/views/referentials/_form.html.slim +++ b/app/views/referentials/_form.html.slim @@ -1,30 +1,24 @@ = simple_form_for @referential, class: 'form' do |form| .row - .col-lg-8.col-md-8.col-sm-7.col-xs-8 + .col-lg-8.col-md-8.col-sm-8.col-xs-8 = form.input :name - if @referential.new_record? - if @referential.created_from - .col-lg-2.col-md-2.col-sm-3.col-xs-2 - = form.input :created_from, disabled: true, input_html: { value: Referential.find(@referential.created_from_id).name } - = form.input :created_from_id, as: :hidden - - .col-lg-2.col-md-2.col-sm-2.col-xs-2 + .col-lg-4.col-md-4.col-sm-4.col-xs-4 = form.input :slug, :input_html => { title: t("formtastic.titles.referential.slug") } + - else - .col-lg-4.col-md-4.col-sm-5.col-xs-4 + .col-lg-4.col-md-4.col-sm-4.col-xs-4 = form.input :slug, :input_html => { title: t("formtastic.titles.referential.slug") } - else - if @referential.created_from - .col-lg-2.col-md-2.col-sm-2.col-xs-2 + .col-lg-4.col-md-4.col-sm-4.col-xs-4 label.control-label = @referential.human_attribute_name('slug') br = @referential.slug - .col-lg-2.col-md-2.col-sm-2.col-xs-2 - label.control-label = @referential.human_attribute_name('created_from') - = @referential.created_from.name - else .col-lg-4.col-md-4.col-sm-4.col-xs-4 label.control-label = @referential.human_attribute_name('slug') @@ -32,13 +26,37 @@ = @referential.slug .row - .col-lg-5.col-md-5.col-sm-5.col-xs-5 - = form.input :prefix, input_html: { title: t("formtastic.titles.referential.prefix") } - .col-lg-7.col-md-7.col-sm-7.col-xs-7 - = form.input :projection_type, as: :select, collection: Referential.available_srids + - if @referential.new_record? + - if @referential.created_from + .col-lg-6.col-md-6.col-sm-6.col-xs-6 + = form.input :created_from, disabled: true, input_html: { value: Referential.find(@referential.created_from_id).name } + = form.input :created_from_id, as: :hidden + + .col-lg-6.col-md-6.col-sm-6.col-xs-6 + = form.input :prefix, input_html: { title: t("formtastic.titles.referential.prefix") } + + - else + .col-lg-12.col-md-12.col-sm-12.col-xs-12 + = form.input :prefix, input_html: { title: t("formtastic.titles.referential.prefix") } + + - else + - if @referential.created_from + .col-lg-6.col-md-6.col-sm-6.col-xs-6 + label.control-label = @referential.human_attribute_name('created_from') + br + = @referential.created_from.name + + .col-lg-6.col-md-6.col-sm-6.col-xs-6 + = form.input :prefix, input_html: { title: t("formtastic.titles.referential.prefix") } + + - else + .col-lg-12.col-md-12.col-sm-12.col-xs-12 + = form.input :prefix, input_html: { title: t("formtastic.titles.referential.prefix") } .row .col-lg-6.col-md-6.col-sm-6.col-xs-6 + = form.input :projection_type, as: :select, collection: Referential.available_srids + .col-lg-6.col-md-6.col-sm-6.col-xs-6 = form.input :time_zone .row style='margin-bottom:20px' @@ -53,7 +71,6 @@ .alert.alert-danger - @referential.errors[:metadatas].each do |msg| p.small = "- #{msg}" - = form.simple_fields_for :metadatas do |subform| = subform.simple_fields_for :periods do |period_form| .row diff --git a/app/views/referentials/_period_fields.html.slim b/app/views/referentials/_period_fields.html.slim index 9d92f92ce..6658cd4aa 100644 --- a/app/views/referentials/_period_fields.html.slim +++ b/app/views/referentials/_period_fields.html.slim @@ -14,3 +14,4 @@ .col-lg-2.col-md-2.col-sm-2.col-xs-2.text-right style='margin-top:23px' = link_to_remove_association f, class: 'btn btn-danger', data: { confirm: 'Etes-vous sûr(e) ?' } do span.fa.fa-trash + diff --git a/app/views/referentials/_reflines.html.slim b/app/views/referentials/_reflines.html.slim new file mode 100644 index 000000000..c0f0e03b7 --- /dev/null +++ b/app/views/referentials/_reflines.html.slim @@ -0,0 +1,15 @@ +- if @reflines && @reflines.any? + p + strong Lignes : + + = table_builder @reflines, + { 'Oid' => Proc.new { |n| n.objectid.local_id }, @reflines.human_attribute_name(:id) => 'id', + @reflines.human_attribute_name(:number) => 'number', @reflines.human_attribute_name(:name) => 'name', @reflines.human_attribute_name(:network) => Proc.new { |n| n.try(:network).try(:name) }, @reflines.human_attribute_name(:company) => Proc.new { |n| n.try(:company).try(:name) } }, + [], + 'table table-bordered' + + .text-center + = will_paginate @reflines, container: false, renderer: BootstrapPagination::Rails + +- else + = replacement_msg t('referential_lines.search_no_results') diff --git a/app/views/referentials/index.html.slim b/app/views/referentials/index.html.slim index b8c16b5ae..8186f725f 100644 --- a/app/views/referentials/index.html.slim +++ b/app/views/referentials/index.html.slim @@ -13,6 +13,7 @@ ul.actions li = link_to 'Données Reflex', stop_area_referential_path(1) li = link_to 'Données CodifLigne', line_referential_path(1) + li= link_to t('calendars.standard_calendars'), calendars_path / FIXME #823 - if false li = link_to t('referentials.actions.new'), new_referential_path, class: 'add' diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim index 7df7efff4..4826f9040 100644 --- a/app/views/referentials/show.html.slim +++ b/app/views/referentials/show.html.slim @@ -34,6 +34,9 @@ h2 => l period.begin => Referential.human_attribute_name("end_validity_period") = l period.end + + #reflines + = render partial: 'reflines' / - if @referential.api_keys.present? / h3.api_keys = t('.api_keys') @@ -43,7 +46,7 @@ h2 - content_for :sidebar do ul.actions - - unless @referential.archived? # FIXME + - if policy(@referential).update? li = link_to t('referentials.actions.edit'), edit_referential_path(@referential), class: 'edit' li = link_to t('referentials.actions.destroy'), referential_path(@referential), method: :delete, data: {:confirm => t('referentials.actions.destroy_confirm')}, class: "remove" @@ -51,7 +54,6 @@ h2 li = link_to t('referentials.actions.clone'), new_referential_path(from: @referential.id), class: 'add' br - - unless @referential.archived? # FIXME + - if policy(@referential).update? h4 = t('.clean_up') - == render 'clean' diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim index 9893e4ed7..ae07d41de 100644 --- a/app/views/routes/_form.html.slim +++ b/app/views/routes/_form.html.slim @@ -29,4 +29,4 @@ | window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}" / StopPoints Reactux component -= javascript_include_tag 'es6_browserified/stop_points.js' += javascript_include_tag 'es6_browserified/itineraries/stop_points.js' diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim index c914030c9..3f0e22006 100644 --- a/app/views/routes/show.html.slim +++ b/app/views/routes/show.html.slim @@ -63,14 +63,32 @@ p.after_map 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") +.panel.panel-default#journey_patterns + .panel-heading + h4.panel-title + strong = t('.journey_patterns') + + .list-group + - @route.journey_patterns.each do |journey_pattern| + .list-group-item.clearfix title="#{t('journey_patterns.journey_pattern.stop_count', count: journey_pattern.stop_points.count, route_count: @route.stop_points.count)} | #{t('journey_patterns.journey_pattern.vehicle_journeys_count', count: journey_pattern.vehicle_journeys.count)}" + span.label.label-default style='margin-right: 10px;' = journey_pattern.objectid.local_id + strong = "#{journey_name(journey_pattern)} " + + - unless journey_pattern.stop_points.empty? + em.small + = t('journey_patterns.journey_pattern.from_to', departure: journey_pattern.stop_points.first.stop_area.name, arrival: journey_pattern.stop_points.last.stop_area.name) + + .btn-group.btn-group-xs.pull-right + .btn.btn-primary.dropdown-toggle data-toggle='dropdown' + span.fa.fa-bars + span.caret + ul.dropdown-menu + li = link_to 'Voir', [@referential, @line, @route, journey_pattern], title: "#{Chouette::JourneyPattern.model_name.human.capitalize} #{journey_name(journey_pattern)}" + li = link_to 'Supprimer', referential_line_route_journey_pattern_path(@referential, @line, @route, journey_pattern), method: :delete, data: {confirm: t('journey_patterns.actions.destroy_confirm')} + + / .panel-body + / .journey_patterns.paginated_content + / = paginated_content( @route.journey_patterns, "journey_patterns/journey_pattern") - content_for :sidebar do ul.actions @@ -86,6 +104,7 @@ p.after_map / 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('journey_patterns.actions.edit_journey_patterns_collection'), [@referential, @line, @route, :journey_patterns_collection], class: 'edit' li = link_to t('vehicle_journeys.actions.index'), [@referential, @line, @route, :vehicle_journeys], class: 'clock' / ul.actions diff --git a/app/views/routing_constraint_zones/_form.html.slim b/app/views/routing_constraint_zones/_form.html.slim new file mode 100644 index 000000000..d9e243746 --- /dev/null +++ b/app/views/routing_constraint_zones/_form.html.slim @@ -0,0 +1,13 @@ += simple_form_for [@referential, @line, @routing_constraint_zone] do |f| + .row + .col-lg-6.col-sm-12 + = f.input :name, label: t('activerecord.models.attributes.routing_constraint_zone.name') + .row + .col-lg-6.col-sm-12 + = f.input :stop_area_ids, as: :select, collection: Chouette::StopArea.all, selected: @routing_constraint_zone.stop_area_ids, label: Chouette::StopArea.model_name.human.pluralize.capitalize, label_method: :name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Sélection de arrêts', 'multiple': 'multiple', style: 'width: 100%' } + + .row + .col-lg-12.text-right + = link_to 'Annuler', :back, class: 'btn btn-link' + = f.button :submit, class: 'btn btn-danger' + diff --git a/app/views/routing_constraint_zones/edit.html.slim b/app/views/routing_constraint_zones/edit.html.slim new file mode 100644 index 000000000..fcb0d08a8 --- /dev/null +++ b/app/views/routing_constraint_zones/edit.html.slim @@ -0,0 +1,5 @@ += title_tag t('.title', routing_constraint_zone: @routing_constraint_zone.name) + +.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/routing_constraint_zones/index.html.slim b/app/views/routing_constraint_zones/index.html.slim new file mode 100644 index 000000000..b12fbd3dd --- /dev/null +++ b/app/views/routing_constraint_zones/index.html.slim @@ -0,0 +1,10 @@ += title_tag Chouette::RoutingConstraintZone.model_name.human.pluralize(:fr) + += link_to t('routing_constraint_zones.actions.new'), new_referential_line_routing_constraint_zone_path + +- if @routing_constraint_zones.any? + = table_builder @routing_constraint_zones, + { @routing_constraint_zones.human_attribute_name(:name) => 'name' }, + [:show, :edit, :delete], + 'table table-bordered' + diff --git a/app/views/routing_constraint_zones/new.html.slim b/app/views/routing_constraint_zones/new.html.slim new file mode 100644 index 000000000..fcb0d08a8 --- /dev/null +++ b/app/views/routing_constraint_zones/new.html.slim @@ -0,0 +1,5 @@ += title_tag t('.title', routing_constraint_zone: @routing_constraint_zone.name) + +.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/routing_constraint_zones/show.html.slim b/app/views/routing_constraint_zones/show.html.slim new file mode 100644 index 000000000..0f88f5b3f --- /dev/null +++ b/app/views/routing_constraint_zones/show.html.slim @@ -0,0 +1,18 @@ += title_tag @routing_constraint_zone.name + +p + label => "#{@routing_constraint_zone.human_attribute_name(:name)} : " + = @routing_constraint_zone.name + +p + label => "#{Chouette::Line.model_name.human.capitalize} : " + = link_to @routing_constraint_zone.line.name, referential_line_path(@referential, @line) + +p + label => "#{Chouette::StopArea.model_name.human.pluralize.capitalize} : " + br + - @routing_constraint_zone.stop_areas.each do |stop_area| + = link_to stop_area.name, referential_stop_area_path(@referential, stop_area) + br + + diff --git a/app/views/shared/_breadcrumb.html.slim b/app/views/shared/_breadcrumb.html.slim index f668db52b..a101098fe 100644 --- a/app/views/shared/_breadcrumb.html.slim +++ b/app/views/shared/_breadcrumb.html.slim @@ -1,2 +1,2 @@ - if @breadcrumbs.present? - = render_breadcrumbs builder: BootstrapBreadcrumbsBuilder, tag: :li, separator: ""
\ No newline at end of file + = render_breadcrumbs builder: BootstrapBreadcrumbsBuilder, tag: :li, separator: '' diff --git a/app/views/shared/_ie_report_file.html.slim b/app/views/shared/_ie_report_file.html.slim index b0cd0b427..edf1e74fa 100644 --- a/app/views/shared/_ie_report_file.html.slim +++ b/app/views/shared/_ie_report_file.html.slim @@ -1,5 +1,5 @@ p.lead - p.caption = t('.title_default', job=job.class.model_name.human extension=job.filename_extension ) + p.caption = t('.title_default', job: job.class.model_name.human, extension: job.filename_extension) .report.results data-refresh-interval="#{job_refresh_interval(job)}" p @@ -27,8 +27,8 @@ p.lead td data-value="#{file.status.downcase}" = t(".table.#{file.status.downcase}") td = file.name - td = file.errors.map |e| "#{e.code} : #{e.description}" .join(' | ') if file.errors.present? + td = file.errors.map{ |e| "#{e.code} : #{e.description}" }.join(' | ') if file.errors.present? tfoot tr td colspan="5" - ul.pagination.pagination-centered
\ No newline at end of file + ul.pagination.pagination-centered diff --git a/app/views/shared/_ie_report_line.html.slim b/app/views/shared/_ie_report_line.html.slim index c2a24f1e4..32816f63b 100644 --- a/app/views/shared/_ie_report_line.html.slim +++ b/app/views/shared/_ie_report_line.html.slim @@ -40,7 +40,7 @@ p.lead - line_items.each_with_index do |line_item, index| tr td data-value="#{line_item.status}" - = line_item.status ? font_awesome_classic_tag(fa-check) : font_awesome_classic_tag(fa-times) + = line_item.status ? font_awesome_classic_tag('fa-check') : font_awesome_classic_tag('fa-times') td = line_item.name td @@ -58,4 +58,4 @@ p.lead - if line_items.respond_to?(:total_pages) = will_paginate line_items, renderer: BootstrapPagination::Rails - else - ul.pagination.pagination-centered.hide-if-no-paging
\ No newline at end of file + ul.pagination.pagination-centered.hide-if-no-paging diff --git a/app/views/shared/_lines_search_form.html.slim b/app/views/shared/_lines_search_form.html.slim index c12ee132b..0d4fedbc0 100644 --- a/app/views/shared/_lines_search_form.html.slim +++ b/app/views/shared/_lines_search_form.html.slim @@ -4,7 +4,7 @@ .input-group.col-md-9.col-sm-9 = f.search_field :name_or_number_or_objectid_cont, placeholder: t('lines.index.name_or_number_or_objectid'), class: 'form-control' .input-group-btn - button.btn.btn-primary type='submit' + button.btn.btn-primary#search-btn type='submit' i.fa.fa-search a data-toggle='collapse' data-parent='#search' href='#advanced_search' diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim index 355f4dc83..546143393 100644 --- a/app/views/stop_areas/_form.html.slim +++ b/app/views/stop_areas/_form.html.slim @@ -7,18 +7,18 @@ = form.inputs do = form.input :id, as: :hidden = form.input :name, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")} - = form.input :stop_area_type, as: :select, :input_html => { :disabled => !@stop_area.new_record? }, :collection => Chouette::StopArea.stop_area_types, :include_blank => false, :member_label => Proc.new { |stop_area_type| t("area_types.label.#{stop_area_type}") } - + = form.input :stop_area_type, as: :select, :input_html => { :disabled => !@stop_area.new_record? }, :collection => Chouette::StopArea.area_type.options, :include_blank => false + .location_info h3 = t("stop_areas.stop_area.localisation") - + #prefetch label = t('.geolocalize') input.typeahead.form-control.input-lg maxlength="255" type="text" placeholder="#{t('.address')}" - unless @stop_area.projection.blank? or @stop_area.projection_type_label.empty? = form.input :projection_xy, :label => t("activerecord.attributes.stop_area.projection_xy", :projection => @referential.projection_type_label), :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.projection_xy")} - + = form.input :coordinates, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.coordinates")} = form.input :street_name = form.input :country_code, required: format_restriction_for_locales(@referential) == '.hub' @@ -27,7 +27,7 @@ .stop_areas.stop_area.general_info h3 = t("stop_areas.stop_area.general") - + = form.inputs do = form.input :objectid, :required => !@stop_area.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.objectid")} = form.input :registration_number, required: format_restriction_for_locales(@referential) == '.hub', :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.registration_number")} @@ -44,7 +44,7 @@ = form.input :mobility_restricted_suitability, as: :select, :collection => [[t("true"), true], [t("false"), false]], :include_blank => true = form.input :stairs_availability, as: :select, :collection => [[t("true"), true], [t("false"), false]], :include_blank => true = form.input :lift_availability, as: :select, :collection => [[t("true"), true], [t("false"), false]], :include_blank => true - + = form.actions do = form.action :submit, as: :button = form.action :cancel, as: :link @@ -150,4 +150,4 @@ javascript: $('input[name="stop_area[city_name]"]').val(datum.city); <% end %> }) - });
\ No newline at end of file + }); diff --git a/app/views/stop_areas/_stop_area.html.slim b/app/views/stop_areas/_stop_area.html.slim index afd6e9385..73c565ce9 100644 --- a/app/views/stop_areas/_stop_area.html.slim +++ b/app/views/stop_areas/_stop_area.html.slim @@ -11,7 +11,7 @@ span.fa.fa-trash-o h5 - = link_to([@stop_area_referential, stop_area], class: 'preview', :title => t("area_types.label.#{stop_area.stop_area_type}") + " #{stop_area.name}") do + = link_to([@stop_area_referential, stop_area], class: 'preview', :title => "#{stop_area.area_type} #{stop_area.name}") do span.name = image_tag "map/" + stop_area.stop_area_type + ".png" = truncate(stop_area.name, :length => 20) diff --git a/app/views/stop_areas/_stop_areas.html.slim b/app/views/stop_areas/_stop_areas.html.slim index e05bab1bc..f976eb327 100644 --- a/app/views/stop_areas/_stop_areas.html.slim +++ b/app/views/stop_areas/_stop_areas.html.slim @@ -1,9 +1,11 @@ -.page_info - span.search = t("will_paginate.page_entries_info.search") - = page_entries_info @stop_areas +- if @stop_areas.any? + = table_builder @stop_areas, + { 'Object_id' => 'objectid', @stop_areas.human_attribute_name(:name) => 'name', @stop_areas.human_attribute_name(:registration_number) => 'registration_number', @stop_areas.human_attribute_name(:city_name) => 'city_name', @stop_areas.human_attribute_name(:zip_code) => 'zip_code' }, + [:show, :edit, :delete], + 'table table-bordered' -.stop_areas.paginated_content - = paginated_content(@stop_areas) + .text-center + = will_paginate @stop_areas, container: false, renderer: RemoteBootstrapPaginationLinkRenderer -.pagination - = will_paginate @stop_areas, :container => false, renderer: RemoteBootstrapPaginationLinkRenderer
\ No newline at end of file +- else + = replacement_msg t('stop_areas.search_no_results') diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim index a02f9b9a8..402d48b28 100644 --- a/app/views/stop_areas/index.html.slim +++ b/app/views/stop_areas/index.html.slim @@ -1,22 +1,17 @@ = title_tag t('stop_areas.index.title') -#country_codes - = @country_codes.to_json - = search_form_for @q, url: stop_area_referential_stop_areas_path(@stop_area_referential), remote: true, html: { method: :get, class: "form", id: "search", role: "form"} do |f| .panel.panel-default .panel-heading .input-group.col-md-9.col-sm-9 = f.text_field :name_or_objectid_cont, placeholder: t('.name_or_objectid'), class: 'form-control' - .input-group-btn - button.btn.btn-primary type="submit" + button.btn.btn-primary#search-btn type="submit" span.fa.fa-search a data-toggle="collapse" data-parent="#search" href="#advanced_search" - i.fa.fa-plus - = "#{t('.advanced_search')}" - + span.fa.fa-plus + = " #{t('.advanced_search')}" #advanced_search.panel-collapse.collapse .panel-body .row @@ -25,7 +20,7 @@ .col-sm-3 = f.text_field :city_name_cont, placeholder: "#{t('.city_name')}", class: 'form-control typeahead', style: 'width: 100%' .col-sm-3 - = f.select(:area_type_cont, options_from_collection_for_select(Chouette::StopArea.stop_area_types, 'name', Proc.new { |stop_area_type| t("area_types.label.#{stop_area_type}") } ), { include_blank: '' }, { class: 'form-control', style: 'width: 100%', 'data-select2ed': 'true', 'data-select2ed-placeholder': t(".area_type") }) + = f.select(:area_type_cont, Chouette::StopArea.area_type.options, { include_blank: t('.area_type') }, { class: 'form-control' }) #stop_areas = render 'stop_areas' diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim index 7194ce363..8652f7cb5 100644 --- a/app/views/time_tables/_form.html.slim +++ b/app/views/time_tables/_form.html.slim @@ -5,9 +5,11 @@ = form.input :tag_search, as: :tags, :input_html => { :id => "tag_search",:placeholder => t("formtastic.placeholders.time_table.tag_search") } = form.input :tag_list, as: :hidden, :input_html => { :id => "tag_list" } = form.input :objectid, :required => !@time_table.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.objectid")} - + - if @time_table.new_record? + = form.input :calendar, as: :select, collection: current_organisation.calendars + h3.time_table_periods = @time_table.human_attribute_name("periods") - + #periods_content = form.inputs class: 'day_type' do label.day_type_label = @time_table.human_attribute_name("day_types") @@ -24,7 +26,7 @@ == render "period_fields", :f => p = link_to_add_association t("time_tables.actions.add_period"), form, :periods , :"data-association-insertion-method" => "append", :"data-association-insertion-node" => "div#periods" - + h3.time_table_dates = @time_table.human_attribute_name("dates") #dates_content @@ -53,9 +55,9 @@ javascript: $("#tag_search").tagsManager({ prefilled: items, output: '#tag_list', - tagsContainer: '#tagsContainer' + tagsContainer: '#tagsContainer' }); - + var time_tables_tag_list = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), queryTokenizer: Bloodhound.tokenizers.whitespace, @@ -68,4 +70,4 @@ javascript: name: 'time_tables_tag_list', displayKey: 'name', source: time_tables_tag_list.ttAdapter() - });
\ No newline at end of file + }); diff --git a/app/views/time_tables/_show_time_table.html.slim b/app/views/time_tables/_show_time_table.html.slim index ccdc4187f..419d13c96 100644 --- a/app/views/time_tables/_show_time_table.html.slim +++ b/app/views/time_tables/_show_time_table.html.slim @@ -24,6 +24,13 @@ #my-tab-content.tab-content #time_tables.tab-pane.active + #associated_calendar + => "#{t('calendars.standard_calendar')} : " + - if @time_table.calendar + = link_to @time_table.calendar.name, @time_table.calendar + - else + = '--' + .well.legend span.title = t(".legend") span.label.excluded_date X @@ -84,4 +91,4 @@ - if @time_table.dates.where("in_out = false").present? h3.time_table_dates = @time_table.human_attribute_name("excluded_dates") .excluded_dates.content - == render "time_tables/excluded_dates"
\ No newline at end of file + == render "time_tables/excluded_dates" diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index a979d85f8..a6cef4904 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -50,7 +50,7 @@ ul.dropdown-menu li = link_to "Voir", referential_path(referential) - - unless referential.archived? # FIXME + - if policy(referential).update? li = link_to "Editer", edit_referential_path(referential) li = link_to "Cloner", new_referential_path(from: referential) diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index b439821d2..8f0eb6c10 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -38,7 +38,8 @@ Apartment.configure do |config| "ReferentialCloning", "Workbench", "CleanUp", - "CleanUpResult" + "CleanUpResult", + "Calendar" ] # use postgres schemas? diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 928236c4a..9ca59134e 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,4 +5,4 @@ Rails.application.config.assets.version = '1.0' # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -Rails.application.config.assets.precompile += %w( es6_browserified/*.js ) +Rails.application.config.assets.precompile += %w( base.css application_new.css es6_browserified/*.js ) diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 5f618b7d5..2dfacf970 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -4,12 +4,13 @@ # Add new inflection rules using the following format. Inflections # are locale specific, and you may define rules for as many different # locales as you wish. All of these examples are active by default: -ActiveSupport::Inflector.inflections(:en) do |inflect| +ActiveSupport::Inflector.inflections(:fr) do |inflect| # inflect.plural /^(ox)$/i, '\1en' # inflect.singular /^(ox)en/i, '\1' # inflect.irregular 'person', 'people' # inflect.uncountable %w( fish sheep ) - inflect.irregular 'réseau', 'réseaux' + inflect.plural 'réseau', 'réseaux' + inflect.plural 'Zone de contrainte', 'Zones de contrainte' end # These inflection rules are supported but not enabled by default: diff --git a/config/locales/actions.en.yml b/config/locales/actions.en.yml index a259ecb8a..ba5bc1506 100644 --- a/config/locales/actions.en.yml +++ b/config/locales/actions.en.yml @@ -4,9 +4,11 @@ en: destroy: "Destroy" search: "Search" add: "Add new" + show: "See" or: "or" cancel: "Cancel" search_hint: "Type in a search term" no_result_text: "No Results" searching_term: "Searching..." + are_you_sure: Are you sure? diff --git a/config/locales/actions.fr.yml b/config/locales/actions.fr.yml index 60daa21f7..16c687458 100644 --- a/config/locales/actions.fr.yml +++ b/config/locales/actions.fr.yml @@ -4,8 +4,10 @@ fr: destroy: "Supprimer" search: "Chercher" add: "Ajouter" + show: "Voir" or: "ou" cancel: "Annuler" search_hint: "Entrez un texte à rechercher" no_result_text: "Aucun résultat" searching_term: "Recherche en cours..." + are_you_sure: Etes vous sûr ? diff --git a/config/locales/area_types.fr.yml b/config/locales/area_types.fr.yml index ddc0a8c56..b5b513368 100644 --- a/config/locales/area_types.fr.yml +++ b/config/locales/area_types.fr.yml @@ -5,4 +5,3 @@ fr: quay: "Quai" commercial_stop_point: "Arrêt commercial" stop_place: "Pôle d'échange" - itl: "ITL" diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml new file mode 100644 index 000000000..cb63afde5 --- /dev/null +++ b/config/locales/calendars.en.yml @@ -0,0 +1,50 @@ +en: + calendars: + standard_calendars: Standard calendars + standard_calendar: Standard calendar + actions: + new: Add a new calendar + edit: Edit this calendar + destroy: Remove this calendar + destroy_confirm: Are you sure you want destroy this calendar? + errors: + overlapped_periods: Another period is overlapped with this period + index: + title: Calendars + all: All + shared: Shared + not_shared: Not shared + search_no_results: No calendar matching your query + date: Date + new: + title: Add a new calendar + edit: + title: Update calendar %{calendar} + show: + title: Calendar %{calendar} + simple_form: + labels: + calendar: + date_value: Date + add_a_date: Add a date + add_a_date_range: Add a date range + ranges: + begin: Beginning + end: End + activerecord: + models: + calendar: Calendar + attributes: + calendar: + name: Name + short_name: Short name + date_ranges: Date ranges + dates: Dates + shared: Shared + errors: + models: + calendar: + attributes: + dates: + date_in_date_ranges: A date can not be in Dates and in Date ranges. + date_in_dates: A date can appear only once in the list of dates. diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml new file mode 100644 index 000000000..fbcc3c8cd --- /dev/null +++ b/config/locales/calendars.fr.yml @@ -0,0 +1,51 @@ +fr: + calendars: + standard_calendars: Calendriers standards + standard_calendar: Calendrier standard + actions: + new: Ajouter un calendrier + edit: Modifier cet calendrier + destroy: Supprimer cet calendrier + destroy_confirm: Etes vous sûr de supprimer cet calendrier ? + errors: + overlapped_periods: Une autre période chevauche cette période + index: + title: Calendriers + all: Tous + shared: Partagées + not_shared: Non partagées + search_no_results: Aucun calendrier ne correspond à votre recherche + date: Date + new: + title: Ajouter un calendrier + edit: + title: Modifier le calendrier %{calendar} + show: + title: Calendrier %{calendar} + simple_form: + labels: + calendar: + date_value: Date + add_a_date: Ajouter une date + add_a_date_range: Ajouter un intervalle de dates + ranges: + begin: Début + end: Fin + activerecord: + models: + calendar: Calendrier + attributes: + calendar: + name: Nom + short_name: Nom court + date_ranges: Intervalles de dates + dates: Dates + shared: Partagé + errors: + models: + calendar: + attributes: + dates: + date_in_date_ranges: Une même date ne peut pas être incluse à la fois dans la liste et dans les intervalles de dates. + date_in_dates: Une même date ne peut pas être incluse plusieurs fois dans la liste. + diff --git a/config/locales/companies.en.yml b/config/locales/companies.en.yml index 706b8e62f..55ad321d8 100644 --- a/config/locales/companies.en.yml +++ b/config/locales/companies.en.yml @@ -1,5 +1,6 @@ en: companies: &en_companies + search_no_results: "No company matching your query" actions: new: "Add a new company" edit: "Edit this company" diff --git a/config/locales/companies.fr.yml b/config/locales/companies.fr.yml index 61967fc2b..4d268a407 100644 --- a/config/locales/companies.fr.yml +++ b/config/locales/companies.fr.yml @@ -1,5 +1,6 @@ fr: companies: &fr_companies + search_no_results: "Aucun transporteur ne correspond à votre recherche" actions: new: "Ajouter un transporteur" edit: "Modifier ce transporteur" diff --git a/config/locales/enumerize.en.yml b/config/locales/enumerize.en.yml index 2f865c9f1..b42f68003 100644 --- a/config/locales/enumerize.en.yml +++ b/config/locales/enumerize.en.yml @@ -85,7 +85,13 @@ en: cableway: Cableway funicular: Funicular other: Other - + stop_area: + area_type: + zdep: ZDEp + zder: ZDEr + zdlp: ZDLp + zdlr: ZDLr + lda: LDA line: transport_mode: interchange: Interchange diff --git a/config/locales/enumerize.fr.yml b/config/locales/enumerize.fr.yml index 33a987359..ecfde38bd 100644 --- a/config/locales/enumerize.fr.yml +++ b/config/locales/enumerize.fr.yml @@ -84,7 +84,13 @@ fr: cableway: Téléphérique funicular: Funiculaire other: Autre - + stop_area: + area_type: + zdep: ZDEp + zder: ZDEr + zdlp: ZDLp + zdlr: ZDLr + lda: LDA line: transport_mode: interchange: Interconnection diff --git a/config/locales/footnotes.en.yml b/config/locales/footnotes.en.yml index 98be688c5..98b6bb2a6 100644 --- a/config/locales/footnotes.en.yml +++ b/config/locales/footnotes.en.yml @@ -1,9 +1,12 @@ en: + notice: + footnotes: + updated: 'Footnotes has been updated' footnotes: actions: - add_footnote: "add footnote" + add_footnote: "add footnote" index: - title: "Footnotes" + title: "Footnotes" activerecord: models: footnote: "footnote" diff --git a/config/locales/footnotes.fr.yml b/config/locales/footnotes.fr.yml index f1a9b2cf5..a3cf2312d 100644 --- a/config/locales/footnotes.fr.yml +++ b/config/locales/footnotes.fr.yml @@ -1,9 +1,12 @@ fr: + notice: + footnotes: + updated: 'Note en bas de page mise à jour' footnotes: actions: add_footnote: "ajouter une note en bas de page" index: - title: "Notes en bas de page" + title: "Notes en bas de page" activerecord: models: footnote: "note en bas de page" diff --git a/config/locales/journey_patterns.en.yml b/config/locales/journey_patterns.en.yml index 856dd6d15..b11c59bb1 100644 --- a/config/locales/journey_patterns.en.yml +++ b/config/locales/journey_patterns.en.yml @@ -11,6 +11,7 @@ en: destroy: "Remove this journey pattern" destroy_confirm: A"re you sure you want destroy this journey pattern ?" edit_route_sections: "Update route sections" + edit_journey_patterns_collection: "Edit journey patterns" new: title: "Add a new journey pattern" edit: diff --git a/config/locales/journey_patterns.fr.yml b/config/locales/journey_patterns.fr.yml index 78860514a..83e77e474 100644 --- a/config/locales/journey_patterns.fr.yml +++ b/config/locales/journey_patterns.fr.yml @@ -11,6 +11,7 @@ fr: destroy: "Supprimer cette mission" destroy_confirm: "Etes vous sûr de vouloir détruire cette mission ?" edit_route_sections: "Modifier les sections de parcours" + edit_journey_patterns_collection: "Modifier les missions" new: title: "Ajouter une mission" edit: diff --git a/config/locales/lines.en.yml b/config/locales/lines.en.yml index c7de51eb6..748064c3d 100644 --- a/config/locales/lines.en.yml +++ b/config/locales/lines.en.yml @@ -1,8 +1,10 @@ en: lines: &en_lines + search_no_results: "No line matching your query" actions: new: "Add a new line" edit: "Edit this line" + edit_footnotes: "Edit line footnotes" destroy: "Remove this line" destroy_confirm: "Are you sure you want destroy this line?" destroy_selection_confirm: "Are you sure you want destroy those lines?" diff --git a/config/locales/lines.fr.yml b/config/locales/lines.fr.yml index 4fc32acc7..b328b7885 100644 --- a/config/locales/lines.fr.yml +++ b/config/locales/lines.fr.yml @@ -1,8 +1,10 @@ fr: lines: &fr_lines + search_no_results: "Aucune ligne ne correspond à votre recherche" actions: new: "Ajouter une ligne" edit: "Modifier cette ligne" + edit_footnotes: "Modifier notes en bas de page" destroy: "Supprimer cette ligne" destroy_confirm: "Etes vous sûr de supprimer cette ligne ?" destroy_selection_confirm: "Etes vous sûr de supprimer cette sélection de lignes ?" diff --git a/config/locales/networks.en.yml b/config/locales/networks.en.yml index f2b256a08..fdec3d45a 100644 --- a/config/locales/networks.en.yml +++ b/config/locales/networks.en.yml @@ -1,5 +1,6 @@ en: networks: &en_networks + search_no_results: "No network matching your query" actions: new: "Add a new network" edit: "Edit this network" @@ -62,5 +63,11 @@ en: name: "maximum 75 characters" registration_number: "Positif integer, unique key, of no more than 8 digits." objectid: "[prefix]:PTNetwork:[unique_key] : prefix contains only alphanumerical or underscore characters, unique_key accepts also minus character. Maximum length of the unique key = 3." + + table: + show: Show + edit: Edit + delete: Delete + referential_networks: <<: *en_networks diff --git a/config/locales/networks.fr.yml b/config/locales/networks.fr.yml index 8d259a9a0..0621a6689 100644 --- a/config/locales/networks.fr.yml +++ b/config/locales/networks.fr.yml @@ -1,5 +1,6 @@ fr: networks: &fr_networks + search_no_results: "Aucun réseau ne correspond à votre recherche" actions: new: "Ajouter un réseau" edit: "Modifier ce réseau" @@ -62,5 +63,11 @@ fr: name: "maximum 75 caractères" registration_number: "Entier positif, clé unique, d'un maximum de 8 chiffres." objectid: "[prefixe]:PTNetwork:[clé_unique] caractères autorisés : alphanumériques et 'souligné' pour le préfixe, la clé unique accepte en plus le 'moins'. Longueur maximale de la clé unique = 3." + + table: + show: Voir + edit: Modifier + delete: Supprimer + referential_networks: <<: *fr_networks diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml index 07af15bc0..17d77e975 100644 --- a/config/locales/referentials.en.yml +++ b/config/locales/referentials.en.yml @@ -71,6 +71,7 @@ en: data_format_restrictions: "Data format constraint" data_format: "Favorite format for export" timebands: "Time bands" + routing_constraint_zone: Zone de contrainte formtastic: titles: referential: diff --git a/config/locales/routing_constraint_zones.en.yml b/config/locales/routing_constraint_zones.en.yml new file mode 100644 index 000000000..10bcd2f62 --- /dev/null +++ b/config/locales/routing_constraint_zones.en.yml @@ -0,0 +1,23 @@ +en: + activerecord: + models: + routing_constraint_zone: Routing constraint zone + attributes: + routing_constraint_zone: + name: Name + stop_areas: Stop areas + line: Line + routing_constraint_zones: + actions: + new: New routing constraint zone + edit: Edit this routing constraint zone + destroy: Delete this routing constraint zone + destroy_confirm: Are you sure you want to delete this routing constraint zone? + new: + title: Add a new routings constraint zone + edit: + title: "Update routing constraint zone %{routing_constraint_zone}" + show: + title: "Routing constraint zone %{routing_constraint_zone}" + index: + diff --git a/config/locales/routing_constraint_zones.fr.yml b/config/locales/routing_constraint_zones.fr.yml new file mode 100644 index 000000000..a4e6ed256 --- /dev/null +++ b/config/locales/routing_constraint_zones.fr.yml @@ -0,0 +1,20 @@ +fr: + activerecord: + models: + routing_constraint_zone: Zone de contrainte + attributes: + routing_constraint_zone: + name: Nom + routing_constraint_zones: + actions: + new: Ajouter une zone de contrainte + edit: Modifier cette zone de contrainte + destroy: Supprimer cette zone de contrainte + destroy_confirm: Etes vous sûr de supprimer cette zone de contrainte ? + new: + title: Ajouter une zone de contrainte + edit: + title: "Modifier la zone de contrainte %{routing_constraint_zone}" + show: + title: "Zone de contrainte %{routing_constraint_zone}" + index: diff --git a/config/locales/stop_areas.en.yml b/config/locales/stop_areas.en.yml index 9e5f605d9..dc1716198 100644 --- a/config/locales/stop_areas.en.yml +++ b/config/locales/stop_areas.en.yml @@ -1,5 +1,6 @@ en: stop_areas: &en_stop_areas + search_no_results: "No stop area matching your query" default_geometry_success: "%{count} modified stop areas" stop_area: no_position: "No Position" diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml index b7d281ebe..946199c68 100644 --- a/config/locales/stop_areas.fr.yml +++ b/config/locales/stop_areas.fr.yml @@ -1,5 +1,6 @@ fr: stop_areas: &fr_stop_areas + search_no_results: "Aucun arrêt ne correspond à votre recherche" default_geometry_success: "%{count} arrêts modifiés" stop_area: no_position: "Pas de position" diff --git a/config/locales/time_tables.fr.yml b/config/locales/time_tables.fr.yml index d2d693c93..46f243580 100644 --- a/config/locales/time_tables.fr.yml +++ b/config/locales/time_tables.fr.yml @@ -42,7 +42,7 @@ fr: selected_date: "Date incluse directement" selected_period: "Date incluse par période" properties_show: - resume: "Validité comprise du %{start_date} au %{end_date}" + resume: "Validité comprise du %{start_date} au %{end_date}" resume_empty: "Calendrier vide" index: comment: "Recherche par nom" @@ -88,6 +88,7 @@ fr: period_end: "au" tag_search: "Etiquettes" tag_list: "Etiquettes" + calendar: Calendrier formtastic: titles: time_table: diff --git a/config/locales/users.fr.yml b/config/locales/users.fr.yml index dcb81b808..f50218605 100644 --- a/config/locales/users.fr.yml +++ b/config/locales/users.fr.yml @@ -20,3 +20,5 @@ fr: user: name: "Nom complet" username: "Nom d'utilisateur" + + diff --git a/config/routes.rb b/config/routes.rb index 74e4b47b5..99effe3e5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -67,6 +67,8 @@ ChouetteIhm::Application.routes.draw do resources :networks end + resources :calendars + resources :referentials do resources :api_keys resources :autocomplete_stop_areas @@ -89,6 +91,7 @@ ChouetteIhm::Application.routes.draw do match 'lines' => 'lines#destroy_all', :via => :delete resources :lines, controller: "referential_lines" do + resource :footnotes, controller: "line_footnotes" delete :index, on: :collection, action: :delete_all collection do get 'name_filter' @@ -98,10 +101,9 @@ ChouetteIhm::Application.routes.draw do get 'edit_boarding_alighting' put 'save_boarding_alighting' end + resource :journey_patterns_collection, :only => [:show, :update] resources :journey_patterns do - member do - get 'new_vehicle_journey' - end + get 'new_vehicle_journey', on: :member resource :route_sections_selector, path: 'sections' do post 'selection' end @@ -114,6 +116,7 @@ ChouetteIhm::Application.routes.draw do resources :vehicle_journey_imports resources :vehicle_journey_exports end + resources :routing_constraint_zones end resources :import_tasks, :only => [:new, :create] diff --git a/db/migrate/20150312104557_set_default_value_for_data_format_in_organisation.rb b/db/migrate/20150312104557_set_default_value_for_data_format_in_organisation.rb index 9efd941c4..03d48e0bb 100644 --- a/db/migrate/20150312104557_set_default_value_for_data_format_in_organisation.rb +++ b/db/migrate/20150312104557_set_default_value_for_data_format_in_organisation.rb @@ -1,22 +1,7 @@ class SetDefaultValueForDataFormatInOrganisation < ActiveRecord::Migration def change - Organisation.all.each do |organisation| - if organisation.data_format.neptune? - organisation.update_attributes :data_format => "neptune" - end - end - Referential.all.each do |referential| - if referential.data_format.neptune? - referential.update_attributes :data_format => "neptune" - elsif referential.data_format.netex? - referential.update_attributes :data_format => "netex" - elsif referential.data_format.gtfs? - referential.update_attributes :data_format => "gtfs" - elsif referential.data_format.hub? - referential.update_attributes :data_format => "hub" - end - end - + Organisation.where(data_format: nil).update_all(data_format: "neptune") + execute "update referentials set data_format = organisations.data_format from organisations where referentials.data_format is null and referentials.organisation_id = organisations.id" change_column :organisations, :data_format, :string, :default => "neptune" end end diff --git a/db/migrate/20161208112130_create_routing_constraint_zones.rb b/db/migrate/20161208112130_create_routing_constraint_zones.rb new file mode 100644 index 000000000..0fa1ef1ae --- /dev/null +++ b/db/migrate/20161208112130_create_routing_constraint_zones.rb @@ -0,0 +1,11 @@ +class CreateRoutingConstraintZones < ActiveRecord::Migration + def change + create_table :routing_constraint_zones do |t| + t.string :name + t.integer :stop_area_ids, array: true + t.belongs_to :line, index: true + + t.timestamps + end + end +end diff --git a/db/migrate/20161208114057_add_trident_fields_to_routing_constraint_zone.rb b/db/migrate/20161208114057_add_trident_fields_to_routing_constraint_zone.rb new file mode 100644 index 000000000..afe9379c0 --- /dev/null +++ b/db/migrate/20161208114057_add_trident_fields_to_routing_constraint_zone.rb @@ -0,0 +1,6 @@ +class AddTridentFieldsToRoutingConstraintZone < ActiveRecord::Migration + def change + add_column :routing_constraint_zones, :objectid, :string, null: false + add_column :routing_constraint_zones, :object_version, :integer + end +end diff --git a/db/migrate/20161208120132_add_other_trident_fields_to_routing_constraint_zone.rb b/db/migrate/20161208120132_add_other_trident_fields_to_routing_constraint_zone.rb new file mode 100644 index 000000000..89ed46a97 --- /dev/null +++ b/db/migrate/20161208120132_add_other_trident_fields_to_routing_constraint_zone.rb @@ -0,0 +1,6 @@ +class AddOtherTridentFieldsToRoutingConstraintZone < ActiveRecord::Migration + def change + add_column :routing_constraint_zones, :creation_time, :datetime + add_column :routing_constraint_zones, :creator_id, :string + end +end diff --git a/db/migrate/20161228092957_create_calendars.rb b/db/migrate/20161228092957_create_calendars.rb new file mode 100644 index 000000000..d8bc89103 --- /dev/null +++ b/db/migrate/20161228092957_create_calendars.rb @@ -0,0 +1,15 @@ +class CreateCalendars < ActiveRecord::Migration + def change + create_table :calendars do |t| + t.string :name + t.string :short_name + t.daterange :date_ranges, array: true + t.date :dates, array: true + t.boolean :shared + t.belongs_to :organisation, index: true + + t.timestamps + end + add_index :calendars, :short_name, unique: true + end +end diff --git a/db/migrate/20170106135000_add_calendar_ref_to_time_tables.rb b/db/migrate/20170106135000_add_calendar_ref_to_time_tables.rb new file mode 100644 index 000000000..9c7b8b578 --- /dev/null +++ b/db/migrate/20170106135000_add_calendar_ref_to_time_tables.rb @@ -0,0 +1,5 @@ +class AddCalendarRefToTimeTables < ActiveRecord::Migration + def change + add_reference :time_tables, :calendar, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index e97ba8e52..c9ef05ab1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161118101544) do +ActiveRecord::Schema.define(version: 20170106135000) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -77,6 +77,20 @@ ActiveRecord::Schema.define(version: 20161118101544) do t.datetime "updated_at" end + create_table "calendars", force: true do |t| + t.string "name" + t.string "short_name" + t.daterange "date_ranges", array: true + t.date "dates", array: true + t.boolean "shared" + t.integer "organisation_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "calendars", ["organisation_id"], :name => "index_calendars_on_organisation_id" + add_index "calendars", ["short_name"], :name => "index_calendars_on_short_name", :unique => true + create_table "clean_up_results", force: true do |t| t.string "message_key" t.hstore "message_attributs" @@ -147,6 +161,22 @@ ActiveRecord::Schema.define(version: 20161118101544) do add_index "connection_links", ["objectid"], :name => "connection_links_objectid_key", :unique => true + create_table "delayed_jobs", force: true do |t| + t.integer "priority", default: 0 + t.integer "attempts", default: 0 + t.text "handler" + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" + create_table "exports", force: true do |t| t.integer "referential_id", limit: 8 t.string "status" @@ -466,6 +496,20 @@ ActiveRecord::Schema.define(version: 20161118101544) do add_index "routes", ["objectid"], :name => "routes_objectid_key", :unique => true + create_table "routing_constraint_zones", force: true do |t| + t.string "name" + t.integer "stop_area_ids", array: true + t.integer "line_id" + t.datetime "created_at" + t.datetime "updated_at" + t.string "objectid", null: false + t.integer "object_version" + t.datetime "creation_time" + t.string "creator_id" + end + + add_index "routing_constraint_zones", ["line_id"], :name => "index_routing_constraint_zones_on_line_id" + create_table "routing_constraints_lines", id: false, force: true do |t| t.integer "stop_area_id", limit: 8 t.integer "line_id", limit: 8 @@ -616,8 +660,10 @@ ActiveRecord::Schema.define(version: 20161118101544) do t.integer "int_day_types", default: 0 t.date "start_date" t.date "end_date" + t.integer "calendar_id" end + add_index "time_tables", ["calendar_id"], :name => "index_time_tables_on_calendar_id" add_index "time_tables", ["objectid"], :name => "time_tables_objectid_key", :unique => true create_table "time_tables_vehicle_journeys", id: false, force: true do |t| @@ -731,6 +777,8 @@ ActiveRecord::Schema.define(version: 20161118101544) do add_index "workbenches", ["stop_area_referential_id"], :name => "index_workbenches_on_stop_area_referential_id" Foreigner.load + add_foreign_key "access_links", "access_points", name: "aclk_acpt_fkey", dependent: :delete + add_foreign_key "group_of_lines_lines", "group_of_lines", name: "groupofline_group_fkey", dependent: :delete add_foreign_key "journey_frequencies", "timebands", name: "journey_frequencies_timeband_id_fk", dependent: :nullify diff --git a/db/seeds.rb b/db/seeds.rb index 24d70f0f1..7526330ed 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -7,9 +7,25 @@ # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) # Mayor.create(:name => 'Emanuel', :city => cities.first) + +stop_area_referential = StopAreaReferential.find_or_create_by(name: "Reflex") +line_referential = LineReferential.find_or_create_by(name: "CodifLigne") + stif = Organisation.find_or_create_by!(name: "STIF") do |org| org.code = 'STIF' end +operator = Organisation.find_or_create_by!(code: 'transporteur-a') do |organisation| + organisation.name = "Transporteur A" +end + +line_referential.add_member stif, owner: true +line_referential.add_member operator + +stop_area_referential.add_member stif, owner: true +stop_area_referential.add_member operator + +line_referential.save +stop_area_referential.save stif.users.find_or_create_by!(username: "admin") do |user| user.email = 'stif-boiv@af83.com' @@ -17,31 +33,16 @@ stif.users.find_or_create_by!(username: "admin") do |user| user.name = "STIF Administrateur" end - -operator = Organisation.find_or_create_by!(code: 'transporteur-a') do |organisation| - organisation.name = "Transporteur A" -end - operator.users.find_or_create_by!(username: "transporteur") do |user| user.email = 'stif-boiv+transporteur@af83.com' user.password = "secret" user.name = "Martin Lejeune" end -stop_area_referential = StopAreaReferential.find_or_create_by(name: "Reflex") do |referential| - referential.add_member stif, owner: true - referential.add_member operator -end - 10.times do |n| stop_area_referential.stop_areas.find_or_create_by name: "Test #{n}", area_type: "Quay", objectid: "StopArea: #{n}" end -line_referential = LineReferential.find_or_create_by(name: "CodifLigne") do |referential| - referential.add_member stif, owner: true - referential.add_member operator -end - LineReferentialSync.find_or_create_by(line_referential: line_referential) StopAreaReferentialSync.find_or_create_by(stop_area_referential: stop_area_referential) diff --git a/doc/dependency_decisions.yml b/doc/dependency_decisions.yml new file mode 100644 index 000000000..d072a465a --- /dev/null +++ b/doc/dependency_decisions.yml @@ -0,0 +1,31 @@ +--- +- - :whitelist + - MIT + - :who: + :why: + :versions: [] + :when: 2016-11-25 09:03:57.649321356 Z +- - :whitelist + - ruby + - :who: + :why: + :versions: [] + :when: 2016-11-25 09:16:40.929896845 Z +- - :whitelist + - Public Domain + - :who: + :why: + :versions: [] + :when: 2016-11-25 09:16:54.433102799 Z +- - :whitelist + - "(GPL-2.0 OR MIT)" + - :who: + :why: + :versions: [] + :when: 2016-11-25 09:17:29.558323791 Z +- - :whitelist + - "(MIT OR Apache-2.0)" + - :who: + :why: + :versions: [] + :when: 2016-11-25 09:17:57.770535039 Z diff --git a/lib/range_ext.rb b/lib/range_ext.rb new file mode 100644 index 000000000..5afb44dee --- /dev/null +++ b/lib/range_ext.rb @@ -0,0 +1,7 @@ +class Range + def intersection(other) + return nil if (self.max < other.begin or other.max < self.begin) + [self.begin, other.begin].max..[self.max, other.max].min + end + alias_method :&, :intersection +end diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb index c62cbe94f..b620051af 100644 --- a/lib/stif/reflex_synchronization.rb +++ b/lib/stif/reflex_synchronization.rb @@ -45,8 +45,9 @@ module Stif time = Benchmark.measure do stop_areas.each do |entry| next unless is_valid_type_of_place_ref?(method, entry) - self.processed << entry['id'] + entry['TypeOfPlaceRef'] = self.stop_area_area_type entry, method self.create_or_update_stop_area entry + self.processed << entry['id'] end end log_processing_time("Create or update StopArea", time.real) @@ -66,7 +67,13 @@ module Stif def is_valid_type_of_place_ref? method, entry return true if entry["TypeOfPlaceRef"].nil? return true if method == 'getOR' && ['ZDL', 'LDA', 'ZDE'].include?(entry["TypeOfPlaceRef"]) - return true if method == 'getOP' && ['ZDE'].include?(entry["TypeOfPlaceRef"]) + return true if method == 'getOP' && ['ZDE', 'ZDL'].include?(entry["TypeOfPlaceRef"]) + end + + def stop_area_area_type entry, method + type = entry['type'] == 'Quay' ? 'zde' : entry['TypeOfPlaceRef'] + type = "#{type.to_s}#{method.last}" unless type == 'LDA' + type.downcase end def set_deleted_stop_area @@ -128,7 +135,7 @@ module Stif stop.stop_area_referential = self.defaut_referential { :name => 'Name', - :area_type => 'type', + :area_type => 'TypeOfPlaceRef', :object_version => 'version', :zip_code => 'PostalRegion', :city_name => 'Town' diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake index 2b584c08b..52bab7aa4 100644 --- a/lib/tasks/ci.rake +++ b/lib/tasks/ci.rake @@ -22,6 +22,11 @@ namespace :ci do git_branch.in?(deploy_envs) ? git_branch : "dev" end + desc "Check security aspects" + task :check_security do + sh "bundle exec bundle-audit check --update" + end + desc "Deploy after CI" task :deploy do sh "cap #{deploy_env} deploy:migrations deploy:seed" @@ -35,3 +40,4 @@ end desc "Run continuous integration tasks (spec, ...)" task :ci => ["ci:setup", "spec", "cucumber", "ci:deploy", "ci:clean"] +# task :ci => ["ci:setup", "spec", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"] diff --git a/package.json b/package.json index 43f8c4c6a..d2e9a56b7 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,8 @@ "license": "MIT", "engines": { "node": ">= 0.10" + }, + "devDependencies": { + "es6-object-assign": "^1.0.3" } } diff --git a/spec/controllers/journey_patterns_collections_controller_spec.rb b/spec/controllers/journey_patterns_collections_controller_spec.rb new file mode 100644 index 000000000..888281036 --- /dev/null +++ b/spec/controllers/journey_patterns_collections_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe JourneyPatternsCollectionsController, :type => :controller do + +end diff --git a/spec/factories/calendars.rb b/spec/factories/calendars.rb new file mode 100644 index 000000000..5f3188bee --- /dev/null +++ b/spec/factories/calendars.rb @@ -0,0 +1,16 @@ +FactoryGirl.define do + factory :calendar do + sequence(:name) { |n| "Calendar #{n}" } + sequence(:short_name) { |n| "Cal #{n}" } + date_ranges { [generate(:date_range)] } + sequence(:dates) { |n| [ Date.yesterday - n, Date.yesterday - 2*n ] } + shared false + organisation + end + + sequence :date_range do |n| + date = Date.today + 2*n + date..(date+1) + end +end + diff --git a/spec/factories/chouette_lines.rb b/spec/factories/chouette_lines.rb index e5be80b10..24b182b83 100644 --- a/spec/factories/chouette_lines.rb +++ b/spec/factories/chouette_lines.rb @@ -4,6 +4,7 @@ FactoryGirl.define do sequence(:name) { |n| "Line #{n}" } sequence(:objectid) { |n| "chouette:test:Line:#{n}" } sequence(:transport_mode) { |n| "bus" } + sequence(:number, 1) association :network, :factory => :network association :company, :factory => :company @@ -23,7 +24,7 @@ FactoryGirl.define do after(:create) do |line, evaluator| create_list(:route, evaluator.routes_count, :line => line) do |route| - create_list(:stop_area, evaluator.stop_areas_count, area_type: "Quay") do |stop_area| + create_list(:stop_area, evaluator.stop_areas_count, area_type: "zdep") do |stop_area| create(:stop_point, :stop_area => stop_area, :route => route) end end @@ -34,7 +35,7 @@ FactoryGirl.define do after(:create) do |line| line.routes.each do |route| route.stop_points.each do |stop_point| - comm = create(:stop_area, :area_type => "CommercialStopPoint") + comm = create(:stop_area, :area_type => "lda") stop_point.stop_area.update_attributes(:parent_id => comm.id) end end diff --git a/spec/factories/chouette_routing_constraint_zones.rb b/spec/factories/chouette_routing_constraint_zones.rb new file mode 100644 index 000000000..9a2529483 --- /dev/null +++ b/spec/factories/chouette_routing_constraint_zones.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :routing_constraint_zone, class: Chouette::RoutingConstraintZone do + sequence(:name) { |n| "Routing constraint zone #{n}" } + stop_area_ids { [create(:stop_area).id, create(:stop_area).id] } + association :line, factory: :line + end +end diff --git a/spec/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb index 5ac22adda..8e92b024b 100644 --- a/spec/factories/chouette_stop_areas.rb +++ b/spec/factories/chouette_stop_areas.rb @@ -3,7 +3,7 @@ FactoryGirl.define do sequence(:objectid) { |n| "test:StopArea:#{n}" } sequence(:name) { |n| "stop_area_#{n}" } sequence(:registration_number) { |n| "test-#{n}" } - area_type "CommercialStopPoint" + area_type { Chouette::StopArea.area_type.values.sample } latitude {10.0 * rand} longitude {10.0 * rand} diff --git a/spec/factories/chouette_time_table.rb b/spec/factories/chouette_time_table.rb index 722c977b2..f462349cf 100644 --- a/spec/factories/chouette_time_table.rb +++ b/spec/factories/chouette_time_table.rb @@ -2,29 +2,30 @@ FactoryGirl.define do factory :time_table_date, :class => Chouette::TimeTableDate do end - + factory :time_table_period, :class => Chouette::TimeTablePeriod do end - + factory :time_table, :class => Chouette::TimeTable do sequence(:comment) { |n| "Timetable #{n}" } sequence(:objectid) { |n| "test:Timetable:#{n}" } sequence(:int_day_types) { (1..7).to_a.map{ |n| 2**(n+1)}.sum } + calendar nil transient do dates_count 4 periods_count 4 end - + after(:create) do |time_table, evaluator| - + 0.upto(4) do |i| time_table.dates << create(:time_table_date, :time_table => time_table, :date => i.days.since.to_date, :in_out => true) end - + start_date = Date.today end_date = start_date + 10 - + 0.upto(4) do |i| time_table.periods << create(:time_table_period, :time_table => time_table, :period_start => start_date, :period_end => end_date) start_date = start_date + 20 @@ -33,5 +34,5 @@ FactoryGirl.define do time_table.save_shortcuts end end - + end diff --git a/spec/features/access_points_spec.rb b/spec/features/access_points_spec.rb index 327c5879a..c16039d67 100644 --- a/spec/features/access_points_spec.rb +++ b/spec/features/access_points_spec.rb @@ -22,21 +22,21 @@ describe "Access points", :type => :feature do describe "show" do - it "displays an access point" do - access_points.each do |ap| - visit referential_stop_area_path(referential, stop_area) - click_link ap.name - expect(page).to have_content(ap.name) - end - end + # it "displays an access point" do + # access_points.each do |ap| + # visit referential_stop_area_path(referential, stop_area) + # click_link ap.name + # expect(page).to have_content(ap.name) + # end + # end - it "displays a map" do - access_points.each do |ap| - visit referential_stop_area_path(referential, stop_area) - click_link ap.name - expect(page).to have_selector("#map.access_point") - end - end + # it "displays a map" do + # access_points.each do |ap| + # visit referential_stop_area_path(referential, stop_area) + # click_link ap.name + # expect(page).to have_selector("#map.access_point") + # end + # end end diff --git a/spec/features/calendars_spec.rb b/spec/features/calendars_spec.rb new file mode 100644 index 000000000..c1701d7c7 --- /dev/null +++ b/spec/features/calendars_spec.rb @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'Calendars', type: :feature do + login_user + + let!(:calendars) { Array.new(2) { create :calendar, organisation_id: 1 } } + let!(:shared_calendar_other_org) { create :calendar, shared: true } + let!(:unshared_calendar_other_org) { create :calendar } + + describe 'index' do + before(:each) { visit calendars_path } + + it 'displays calendars of the current organisation and shared calendars' do + expect(page).to have_content(calendars.first.short_name) + expect(page).to have_content(shared_calendar_other_org.short_name) + expect(page).not_to have_content(unshared_calendar_other_org.short_name) + end + + context 'filtering' do + it 'supports filtering by short name' do + fill_in 'q[short_name_cont]', with: calendars.first.short_name + click_button 'search-btn' + expect(page).to have_content(calendars.first.short_name) + expect(page).not_to have_content(calendars.last.short_name) + end + + it 'supports filtering by shared' do + shared_calendar = create :calendar, organisation_id: 1, shared: true + visit calendars_path + select I18n.t('calendars.index.shared'), from: 'q[shared_eq]' + click_button 'search-btn' + expect(page).to have_content(shared_calendar.short_name) + expect(page).not_to have_content(calendars.first.short_name) + end + + it 'supports filtering by date' do + july_calendar = create :calendar, dates: [Date.new(2017, 7, 7)], date_ranges: [Date.new(2017, 7, 15)..Date.new(2017, 7, 30)], organisation_id: 1 + visit calendars_path + fill_in 'q_contains_date', with: '2017/07/07' + click_button 'search-btn' + expect(page).to have_content(july_calendar.short_name) + expect(page).not_to have_content(calendars.first.short_name) + fill_in 'q_contains_date', with: '2017/07/18' + click_button 'search-btn' + expect(page).to have_content(july_calendar.short_name) + expect(page).not_to have_content(calendars.first.short_name) + end + end + end + + describe 'show' do + it 'displays calendar' do + visit calendar_path(calendars.first) + expect(page).to have_content(calendars.first.name) + end + end +end + diff --git a/spec/features/companies_spec.rb b/spec/features/companies_spec.rb index 08221f637..b8e85194c 100644 --- a/spec/features/companies_spec.rb +++ b/spec/features/companies_spec.rb @@ -8,19 +8,41 @@ describe "Companies", :type => :feature do let!(:companies) { Array.new(2) { create :company, line_referential: line_referential } } subject { companies.first } - describe "list" do - it "display companies" do - visit line_referential_companies_path(line_referential) + describe "index" do + before(:each) { visit line_referential_companies_path(line_referential) } + + it "displays companies" do expect(page).to have_content(companies.first.short_name) expect(page).to have_content(companies.last.short_name) end + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_objectid_cont]', with: companies.first.name + click_button 'search-btn' + expect(page).to have_content(companies.first.name) + expect(page).not_to have_content(companies.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_objectid_cont]', with: companies.first.objectid + click_button 'search-btn' + expect(page).to have_content(companies.first.name) + expect(page).not_to have_content(companies.last.name) + end + end + end + + describe "show" do + it "displays line" do + visit line_referential_company_path(line_referential, companies.first) + expect(page).to have_content(companies.first.name) + end end # describe "show" do # it "display company" do # visit line_referential_companies_path(line_referential) - # click_link "#{companies.first.name}" # expect(page).to have_content(companies.first.name) # end # diff --git a/spec/features/group_of_lines_spec.rb b/spec/features/group_of_lines_spec.rb index 5b9522591..79500fe33 100644 --- a/spec/features/group_of_lines_spec.rb +++ b/spec/features/group_of_lines_spec.rb @@ -16,16 +16,26 @@ describe "Group of lines", :type => :feature do subject.lines << line end - describe "list" do - it "display group of lines" do - visit line_referential_group_of_lines_path(line_referential) + describe "index" do + before(:each) { visit line_referential_group_of_lines_path(line_referential) } + + it "displays groups of lines" do expect(page).to have_content(group_of_lines.first.name) expect(page).to have_content(group_of_lines.last.name) end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_cont]', with: group_of_lines.first.name + click_button 'search-btn' + expect(page).to have_content(group_of_lines.first.name) + expect(page).not_to have_content(group_of_lines.last.name) + end + end end describe "show" do - it "display group of line" do + it "displays group of line" do visit line_referential_group_of_lines_path(line_referential) click_link "#{subject.name}" expect(page).to have_content(subject.name) diff --git a/spec/features/line_footnotes_spec.rb b/spec/features/line_footnotes_spec.rb new file mode 100644 index 000000000..a3eab103a --- /dev/null +++ b/spec/features/line_footnotes_spec.rb @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'Line Footnotes', type: :feature do + login_user + + let(:referential) { Referential.first } + #let!(:line_referential) { create :line_referential } + let!(:network) { create(:network) } + let!(:company) { create(:company) } + let!(:line) { create :line_with_stop_areas, network: network, company: company, line_referential: referential.line_referential } + let!(:footnotes) { Array.new(2) { create :footnote, line: line } } + subject { footnotes.first } + + describe 'index' do + before(:each) { visit referential_line_footnotes_path(referential.line_referential, line) } + + it 'displays line footnotes' do + expect(page).to have_content(subject.label) + expect(page).to have_content(subject.label) + end + + it 'allows R and U in CRUD' do + expect(page).to have_content(I18n.t('actions.edit')) + expect(page).not_to have_content(I18n.t('actions.show')) # they're just displayed in index view + expect(page).not_to have_content(I18n.t('actions.destroy')) + expect(page).not_to have_content(I18n.t('actions.add')) + end + end +end diff --git a/spec/features/lines_spec.rb b/spec/features/lines_spec.rb index f6f351049..4ecefab33 100644 --- a/spec/features/lines_spec.rb +++ b/spec/features/lines_spec.rb @@ -11,19 +11,48 @@ describe "Lines", :type => :feature do let!(:group_of_line) { create(:group_of_line) } subject { lines.first } - describe "list" do - it "display lines" do - visit line_referential_lines_path(line_referential) + describe "index" do + before(:each) { visit line_referential_lines_path(line_referential) } + + it "displays lines" do expect(page).to have_content(lines.first.name) expect(page).to have_content(lines.last.name) end + it 'allows only R in CRUD' do + expect(page).to have_content(I18n.t('actions.show')) + expect(page).not_to have_content(I18n.t('actions.edit')) + expect(page).not_to have_content(I18n.t('actions.destroy')) + expect(page).not_to have_content(I18n.t('actions.add')) + end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.name + click_button 'search-btn' + expect(page).to have_content(lines.first.name) + expect(page).not_to have_content(lines.last.name) + end + + it 'supports filtering by number' do + fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.number + click_button 'search-btn' + expect(page).to have_content(lines.first.name) + expect(page).not_to have_content(lines.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_number_or_objectid_cont]', with: lines.first.objectid + click_button 'search-btn' + expect(page).to have_content(lines.first.name) + expect(page).not_to have_content(lines.last.name) + end + end end describe "show" do - it "display line" do - visit line_referential_lines_path(line_referential) - click_link "#{lines.first.name}" + it "displays line" do + visit line_referential_line_path(line_referential, lines.first) expect(page).to have_content(lines.first.name) end end diff --git a/spec/features/networks_spec.rb b/spec/features/networks_spec.rb index f671aa938..3e3be8ef1 100644 --- a/spec/features/networks_spec.rb +++ b/spec/features/networks_spec.rb @@ -8,20 +8,34 @@ describe "Networks", :type => :feature do let!(:networks) { Array.new(2) { create(:network, line_referential: line_referential) } } subject { networks.first } - describe "list" do - it "display networks" do - visit line_referential_networks_path(line_referential) + describe "index" do + before(:each) { visit line_referential_networks_path(line_referential) } + + it "displays networks" do expect(page).to have_content(networks.first.name) expect(page).to have_content(networks.last.name) end + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_objectid_cont]', with: networks.first.name + click_button 'search-btn' + expect(page).to have_content(networks.first.name) + expect(page).not_to have_content(networks.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_objectid_cont]', with: networks.first.objectid + click_button 'search-btn' + expect(page).to have_content(networks.first.name) + expect(page).not_to have_content(networks.last.name) + end + end end describe "show" do - it "display network" do - # allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) }) - visit line_referential_networks_path(line_referential) - click_link "#{networks.first.name}" + it "displays network" do + visit line_referential_network_path(line_referential, networks.first) expect(page).to have_content(networks.first.name) end diff --git a/spec/features/referential_companies_spec.rb b/spec/features/referential_companies_spec.rb new file mode 100644 index 000000000..82f86b192 --- /dev/null +++ b/spec/features/referential_companies_spec.rb @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'ReferentialCompanies', type: :feature do + login_user + + let(:referential) { Referential.first } + let!(:companies) { Array.new(2) { create :company, line_referential: referential.line_referential } } + + describe 'index' do + before(:each) { visit referential_companies_path(referential) } + + it 'displays referential companies' do + expect(page).to have_content(companies.first.name) + expect(page).to have_content(companies.last.name) + end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_objectid_cont]', with: companies.first.name + click_button 'search-btn' + expect(page).to have_content(companies.first.name) + expect(page).not_to have_content(companies.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_objectid_cont]', with: companies.first.objectid + click_button 'search-btn' + expect(page).to have_content(companies.first.name) + expect(page).not_to have_content(companies.last.name) + end + end + end + + describe 'show' do + it 'displays referential company' do + visit referential_company_path(referential, companies.first) + expect(page).to have_content(companies.first.name) + end + end +end diff --git a/spec/features/referential_group_of_lines_spec.rb b/spec/features/referential_group_of_lines_spec.rb new file mode 100644 index 000000000..e5970545b --- /dev/null +++ b/spec/features/referential_group_of_lines_spec.rb @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'ReferentialLines', type: :feature do + login_user + + let(:referential) { Referential.first } + let!(:group_of_lines) { Array.new(2) { create(:group_of_line, line_referential: referential.line_referential) } } + + describe 'index' do + before(:each) { visit referential_group_of_lines_path(referential) } + + it 'displays referential groups of lines' do + expect(page).to have_content(group_of_lines.first.name) + expect(page).to have_content(group_of_lines.last.name) + end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_cont]', with: group_of_lines.first.name + click_button 'search-btn' + expect(page).to have_content(group_of_lines.first.name) + expect(page).not_to have_content(group_of_lines.last.name) + end + end + end + + describe 'show' do + it 'displays referential group of lines' do + visit referential_group_of_line_path(referential, group_of_lines.first) + expect(page).to have_content(group_of_lines.first.name) + end + end +end diff --git a/spec/features/referential_lines_spec.rb b/spec/features/referential_lines_spec.rb new file mode 100644 index 000000000..580891c69 --- /dev/null +++ b/spec/features/referential_lines_spec.rb @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'ReferentialLines', type: :feature do + login_user + let!(:referential_metadata) { create :referential_metadata, referential: referential } + + describe 'index' do + before(:each) { visit referential_lines_path(referential) } + + it 'displays referential lines' do + expect(page).to have_content(referential.lines.first.name) + expect(page).to have_content(referential.lines.last.name) + end + + it 'allows only R in CRUD' do + expect(page).to have_content(I18n.t('actions.show')) + expect(page).not_to have_content(I18n.t('actions.edit')) + expect(page).not_to have_content(I18n.t('actions.destroy')) + expect(page).not_to have_content(I18n.t('actions.add')) + end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_number_or_objectid_cont]', with: referential.lines.first.name + click_button 'search-btn' + expect(page).to have_content(referential.lines.first.name) + expect(page).not_to have_content(referential.lines.last.name) + end + + it 'supports filtering by number' do + fill_in 'q[name_or_number_or_objectid_cont]', with: referential.lines.first.number + click_button 'search-btn' + expect(page).to have_content(referential.lines.first.name) + expect(page).not_to have_content(referential.lines.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_number_or_objectid_cont]', with: referential.lines.first.objectid + click_button 'search-btn' + expect(page).to have_content(referential.lines.first.name) + expect(page).not_to have_content(referential.lines.last.name) + end + end + end + + describe 'show' do + it 'displays referential line' do + visit referential_line_path(referential, referential.lines.first) + expect(page).to have_content(referential.lines.first.name) + end + end +end diff --git a/spec/features/referential_networks_spec.rb b/spec/features/referential_networks_spec.rb new file mode 100644 index 000000000..8eb38df4b --- /dev/null +++ b/spec/features/referential_networks_spec.rb @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'ReferentialNetworks', type: :feature do + login_user + + let(:referential) { Referential.first } + let!(:networks) { Array.new(2) { create :network, line_referential: referential.line_referential } } + + describe 'index' do + before(:each) { visit referential_networks_path(referential) } + + it 'displays referential networks' do + expect(page).to have_content(networks.first.name) + expect(page).to have_content(networks.last.name) + end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_objectid_cont]', with: networks.first.name + click_button 'search-btn' + expect(page).to have_content(networks.first.name) + expect(page).not_to have_content(networks.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_objectid_cont]', with: networks.first.objectid + click_button 'search-btn' + expect(page).to have_content(networks.first.name) + expect(page).not_to have_content(networks.last.name) + end + end + end + + describe 'show' do + it 'displays referential network' do + visit referential_network_path(referential, networks.first) + expect(page).to have_content(networks.first.name) + end + end +end diff --git a/spec/features/referential_stop_areas_spec.rb b/spec/features/referential_stop_areas_spec.rb new file mode 100644 index 000000000..0dc7951a7 --- /dev/null +++ b/spec/features/referential_stop_areas_spec.rb @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'ReferentialStopAreas', type: :feature do + login_user + + let(:referential) { Referential.first } + let(:stop_area_referential) { create :stop_area_referential } + let!(:stop_areas) { Array.new(2) { create :stop_area, stop_area_referential: stop_area_referential } } + + describe 'index' do + before(:each) { visit referential_stop_areas_path(referential) } + + it 'displays referential stop_areas' do + expect(page).to have_content(stop_areas.first.name) + expect(page).to have_content(stop_areas.last.name) + end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_objectid_cont]', with: stop_areas.first.name + click_button 'search-btn' + expect(page).to have_content(stop_areas.first.name) + expect(page).not_to have_content(stop_areas.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_objectid_cont]', with: stop_areas.first.objectid + click_button 'search-btn' + expect(page).to have_content(stop_areas.first.name) + expect(page).not_to have_content(stop_areas.last.name) + end + end + end + + describe 'show' do + it 'displays referential stop area' do + visit referential_stop_area_path(referential, stop_areas.first) + expect(page).to have_content(stop_areas.first.name) + end + end +end diff --git a/spec/features/routes_spec.rb b/spec/features/routes_spec.rb index e5f21ee73..5aea98c90 100644 --- a/spec/features/routes_spec.rb +++ b/spec/features/routes_spec.rb @@ -13,7 +13,7 @@ describe "Routes", :type => :feature do describe "from lines page to a line page" do it "display line's routes" do visit referential_lines_path(referential) - click_link "#{line.name}" + first(:link, 'Voir').click expect(page).to have_content(route.name) expect(page).to have_content(route2.name) end diff --git a/spec/features/routing_constraint_zone_spec.rb b/spec/features/routing_constraint_zone_spec.rb new file mode 100644 index 000000000..6d82323e1 --- /dev/null +++ b/spec/features/routing_constraint_zone_spec.rb @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe 'RoutingConstraintZones', type: :feature do + login_user + + let(:referential) { Referential.first } + let!(:line) { create :line } + let!(:routing_constraint_zones) { Array.new(2) { create :routing_constraint_zone, line: line } } + + describe 'index' do + before(:each) { visit referential_line_routing_constraint_zones_path(referential, line) } + + it 'displays referential routing constraint zones' do + expect(page).to have_content(routing_constraint_zones.first.name) + expect(page).to have_content(routing_constraint_zones.last.name) + end + end + + describe 'show' do + it 'displays referential routing constraint zone' do + visit referential_line_routing_constraint_zone_path(referential, line, routing_constraint_zones.first) + expect(page).to have_content(routing_constraint_zones.first.name) + end + end +end diff --git a/spec/features/stop_areas_spec.rb b/spec/features/stop_areas_spec.rb index 58ff2e78a..a2ed781d1 100644 --- a/spec/features/stop_areas_spec.rb +++ b/spec/features/stop_areas_spec.rb @@ -8,24 +8,41 @@ describe "StopAreas", :type => :feature do let!(:stop_areas) { Array.new(2) { create :stop_area, stop_area_referential: stop_area_referential } } subject { stop_areas.first } - describe "list" do - it "display stop_areas" do - visit stop_area_referential_stop_areas_path(stop_area_referential) + describe "index" do + before(:each) { visit stop_area_referential_stop_areas_path(stop_area_referential) } + + it "displays stop_areas" do expect(page).to have_content(stop_areas.first.name) expect(page).to have_content(stop_areas.last.name) end + + context 'filtering' do + it 'supports filtering by name' do + fill_in 'q[name_or_objectid_cont]', with: stop_areas.first.name + click_button 'search-btn' + expect(page).to have_content(stop_areas.first.name) + expect(page).not_to have_content(stop_areas.last.name) + end + + it 'supports filtering by objectid' do + fill_in 'q[name_or_objectid_cont]', with: stop_areas.first.objectid + click_button 'search-btn' + expect(page).to have_content(stop_areas.first.name) + expect(page).not_to have_content(stop_areas.last.name) + end + end end describe "show" do - it "display stop_area" do - visit stop_area_referential_stop_areas_path(stop_area_referential) - click_link "#{stop_areas.first.name}" + it "displays stop_area" do + visit stop_area_referential_stop_area_path(stop_area_referential, stop_areas.first) expect(page).to have_content(stop_areas.first.name) end it "display map" do visit stop_area_referential_stop_areas_path(stop_area_referential) - click_link "#{stop_areas.first.name}" + # click_link "#{stop_areas.first.name}" + visit stop_area_referential_stop_area_path(stop_area_referential, stop_areas.first) expect(page).to have_selector("#map.stop_area") end diff --git a/spec/javascripts/actions_spec.js b/spec/javascripts/itineraries/actions_spec.js index 55de1c31f..f86466375 100644 --- a/spec/javascripts/actions_spec.js +++ b/spec/javascripts/itineraries/actions_spec.js @@ -1,4 +1,4 @@ -var actions = require('es6_browserified/actions') +var actions = require('es6_browserified/itineraries/actions') describe('actions', () => { it('should create an action to add a stop', () => { diff --git a/spec/javascripts/itineraries/components_spec.js b/spec/javascripts/itineraries/components_spec.js new file mode 100644 index 000000000..c9c57b5eb --- /dev/null +++ b/spec/javascripts/itineraries/components_spec.js @@ -0,0 +1,40 @@ +// var React = require('react'); +// var Provider = require('react-redux').Provider; +// var actions = require('es6_browserified/itineraries/actions/index'); +// var App = require('es6_browserified/itineraries/components/TodoList'); +// var ConnectedApp = require('es6_browserified/itineraries/containers/VisibleTodoList'); +// var TestUtils = require('react-addons-test-utils'); + +// xdescribe('ConnectedApp', function() { +// var connectedApp, store, initialItems; +// var state; +// state = [ +// { +// text: 'first', +// index: 0, +// for_boarding: 'normal', +// for_alighting: 'normal' +// }, +// { +// text: 'second', +// index: 1, +// for_boarding: 'normal', +// for_alighting: 'normal' +// } +// ] + +// beforeEach(function() { +// store = state +// }); + +// describe('state provided by the store', function() { +// beforeEach(function() { +// connectedApp = TestUtils.renderIntoDocument(<Provider store={store}><ConnectedApp/></Provider>); +// }); + +// it('passes down items', function() { +// app = TestUtils.findRenderedComponentWithType(connectedApp, App); +// expect(app.props.items).toEqual(initialItems); +// }); +// }); +// }); diff --git a/spec/javascripts/reducers_spec.js b/spec/javascripts/itineraries/reducers_spec.js index a4880e73e..a8731af5f 100644 --- a/spec/javascripts/reducers_spec.js +++ b/spec/javascripts/itineraries/reducers_spec.js @@ -1,4 +1,4 @@ -var reducer = require('es6_browserified/reducers/todos') +var reducer = require('es6_browserified/itineraries/reducers/todos') let state = [] describe('stops reducer', () => { beforeEach(()=>{ @@ -119,15 +119,15 @@ describe('stops reducer', () => { ) }) - //TODO unskip when es6 is properly functionnal - xit('should handle UPDATE_INPUT_VALUE', () => { + it('should handle UPDATE_INPUT_VALUE', () => { expect( reducer(state, { type: 'UPDATE_INPUT_VALUE', index: 0, text: { text: "new value", - stoparea_id: 1 + stoparea_id: 1, + user_objectid: "1234" } }) ).toEqual( @@ -135,9 +135,11 @@ describe('stops reducer', () => { { text: 'new value', index: 0, + stoppoint_id: '', stoparea_id: 1, for_boarding: 'normal', - for_alighting: 'normal' + for_alighting: 'normal', + user_objectid: "1234" }, { text: 'second', @@ -149,7 +151,7 @@ describe('stops reducer', () => { ) }) - xit('should handle UPDATE_SELECT_VALUE', () => { + it('should handle UPDATE_SELECT_VALUE', () => { expect( reducer(state, { type :'UPDATE_SELECT_VALUE', @@ -160,9 +162,8 @@ describe('stops reducer', () => { ).toEqual( [ { - text: 'new value', + text: 'first', index: 0, - stoparea_id: 1, for_boarding: 'prohibited', for_alighting: 'normal' }, diff --git a/spec/javascripts/journey_patterns/actions_spec.js b/spec/javascripts/journey_patterns/actions_spec.js new file mode 100644 index 000000000..ced053935 --- /dev/null +++ b/spec/javascripts/journey_patterns/actions_spec.js @@ -0,0 +1,133 @@ +var actions = require('es6_browserified/journey_patterns/actions') + +const dispatch = function(){} +const currentPage = 1 + +describe('when receiveJourneyPatterns is triggered', () => { + it('should create an action to pass json to reducer', () => { + const json = undefined + const expectedAction = { + type: 'RECEIVE_JOURNEY_PATTERNS', + json + } + expect(actions.receiveJourneyPatterns()).toEqual(expectedAction) + }) +}) + +describe('when landing on page', () => { + it('should create an action to load the n first missions', () => { + const expectedAction = { + type: 'LOAD_FIRST_PAGE', + dispatch + } + expect(actions.loadFirstPage(dispatch)).toEqual(expectedAction) + }) +}) +describe('when next navigation button is clicked', () => { + it('should create an action to go to next page', () => { + const nextPage = true + const expectedAction = { + type: 'GO_TO_NEXT_PAGE', + dispatch, + currentPage, + nextPage + } + expect(actions.goToNextPage(dispatch, currentPage)).toEqual(expectedAction) + }) +}) +describe('when clicking on a journey pattern checkbox', () => { + it('should create an action to update journey pattern stop points', () => { + const event = { + currentTarget: { + id: '1' + } + } + const index = 1 + const expectedAction = { + type: 'UPDATE_CHECKBOX_VALUE', + id: event.currentTarget.id, + index, + } + expect(actions.updateCheckboxValue(event, index)).toEqual(expectedAction) + }) +}) +describe('when clicking on next button', () => { + it('should create an action to open a confirm modal', () => { + const accept = {}, cancel = {} + const expectedAction = { + type: 'OPEN_CONFIRM_MODAL', + accept, + cancel, + } + expect(actions.openConfirmModal(accept, cancel)).toEqual(expectedAction) + }) +}) +describe('when clicking on edit button', () => { + it('should create an action to open a edit modal', () => { + const index = 1 + const journeyPattern = {} + const expectedAction = { + type: 'EDIT_JOURNEYPATTERN_MODAL', + index, + journeyPattern, + } + expect(actions.openEditModal(index, journeyPattern)).toEqual(expectedAction) + }) +}) +describe('when clicking on add button', () => { + it('should create an action to open a create modal', () => { + const expectedAction = { + type: 'CREATE_JOURNEYPATTERN_MODAL', + } + expect(actions.openCreateModal()).toEqual(expectedAction) + }) +}) +describe('when clicking on close button inside edit or add modal', () => { + it('should create an action to close modal', () => { + const expectedAction = { + type: 'CLOSE_MODAL', + } + expect(actions.closeModal()).toEqual(expectedAction) + }) +}) +describe('when clicking on a journey pattern delete button', () => { + it('should create an action to delete journey pattern', () => { + const index = 1 + const expectedAction = { + type: 'DELETE_JOURNEYPATTERN', + index + } + expect(actions.deleteJourneyPattern(index)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside edit modal', () => { + it('should create an action to save journey pattern modifications', () => { + const index = 1 + const data = {} + const expectedAction = { + type: 'SAVE_MODAL', + index, + data + } + expect(actions.saveModal(index, data)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside create modal', () => { + it('should create an action to create a new journey pattern', () => { + const data = {} + const expectedAction = { + type: 'ADD_JOURNEYPATTERN', + data + } + expect(actions.addJourneyPattern(data)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button at the bottom of the page', () => { + it('should create an action to post data and save it into db', () => { + const expectedAction = { + type: 'SAVE_PAGE', + dispatch + } + expect(actions.savePage(dispatch)).toEqual(expectedAction) + }) +}) diff --git a/spec/javascripts/journey_patterns/reducers/journey_patterns_spec.js b/spec/javascripts/journey_patterns/reducers/journey_patterns_spec.js new file mode 100644 index 000000000..422c97fee --- /dev/null +++ b/spec/javascripts/journey_patterns/reducers/journey_patterns_spec.js @@ -0,0 +1,104 @@ +var jpReducer = require('es6_browserified/journey_patterns/reducers/journeyPatterns') +let state = [] +let fakeStopPoints = [{ + area_type : "lda", + checked : false, + id : 45289, + name : "Clichy Levallois", + object_id : "FR:92044:LDA:72073:STIF", + object_version : 1, + position : 0, +},{ + area_type : "lda", + checked : false, + id : 40534, + name : "Thomas Lemaître", + object_id : "FR:92050:LDA:70915:STIF", + object_version : 1, + position : 1, +}] + +describe('journeyPatterns reducer', () => { + beforeEach(()=>{ + state = [ + { + deletable: false, + name: 'm1', + object_id : 'o1', + published_name: 'M1', + registration_number: '', + stop_points: fakeStopPoints + }, + { + deletable: false, + name: 'm2', + object_id : 'o2', + published_name: 'M2', + registration_number: '', + stop_points: fakeStopPoints + } + ] + }) + + it('should return the initial state', () => { + expect( + jpReducer(undefined, {}) + ).toEqual([]) + }) + + it('should handle ADD_JOURNEYPATTERN', () => { + let fakeData = { + name: {value : 'm3'}, + published_name: {value: 'M3'}, + registration_number: {value: ''} + } + expect( + jpReducer(state, { + type: 'ADD_JOURNEYPATTERN', + data: fakeData + }) + ).toEqual([...state, { + name : 'm3', + published_name: 'M3', + registration_number: '', + deletable: false, + stop_points: fakeStopPoints + }]) + }) + + it('should handle UPDATE_CHECKBOX_VALUE', () => { + let newFirstStopPoint = Object.assign({}, fakeStopPoints[0], {checked: !fakeStopPoints[0].checked} ) + let newStopPoints = [newFirstStopPoint, fakeStopPoints[1]] + let newState = Object.assign({}, state[0], {stop_points: newStopPoints}) + expect( + jpReducer(state, { + type: 'UPDATE_CHECKBOX_VALUE', + id: 45289, + index: 0 + }) + ).toEqual([newState, state[1]]) + }) + + it('should handle DELETE_JOURNEYPATTERN', () => { + expect( + jpReducer(state, { + type: 'DELETE_JOURNEYPATTERN', + index: 1 + }) + ).toEqual([state[0], Object.assign({}, state[1], {deletable: true})]) + }) + it('should handle SAVE_MODAL', () => { + let newState = Object.assign({}, state[0], {name: 'p1', published_name: 'P1', registration_number: 'PP11'}) + expect( + jpReducer(state, { + type: 'SAVE_MODAL', + data: { + name: {value: 'p1'}, + published_name: {value: 'P1'}, + registration_number: {value: 'PP11'} + }, + index: 0 + }) + ).toEqual([newState, state[1]]) + }) +}) diff --git a/spec/javascripts/journey_patterns/reducers/modal_spec.js b/spec/javascripts/journey_patterns/reducers/modal_spec.js new file mode 100644 index 000000000..ee83cb251 --- /dev/null +++ b/spec/javascripts/journey_patterns/reducers/modal_spec.js @@ -0,0 +1,100 @@ +var modalReducer = require('es6_browserified/journey_patterns/reducers/modal') + +let state = {} + +let fakeJourneyPattern = { + name: 'jp_test 1', + object_id: 'jp_test:JourneyPattern:1', + published_name: 'jp_test publishedname 1', + registration_number: 'jp_test registrationnumber 1', + stop_points: [], + deletable: false +} + +const accept = cancel = function(){} + +describe('modal reducer', () => { + beforeEach(() => { + state = { + type: '', + modalProps: {}, + confirmModal: {} + } + }) + + it('should return the initial state', () => { + expect( + modalReducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle OPEN_CONFIRM_MODAL', () => { + let newState = Object.assign({}, state, { + type: 'confirm', + confirmModal: { + accept: accept, + cancel: cancel + } + }) + expect( + modalReducer(state, { + type: 'OPEN_CONFIRM_MODAL', + accept, + cancel + }) + ).toEqual(newState) + }) + + it('should handle EDIT_JOURNEYPATTERN_MODAL', () => { + let newState = Object.assign({}, state, { + type: 'edit', + modalProps: { + index: 0, + journeyPattern: fakeJourneyPattern + }, + confirmModal: {} + }) + expect( + modalReducer(state, { + type: 'EDIT_JOURNEYPATTERN_MODAL', + index: 0, + journeyPattern : fakeJourneyPattern + }) + ).toEqual(newState) + }) + + it('should handle CREATE_JOURNEYPATTERN_MODAL', () => { + expect( + modalReducer(state, { + type: 'CREATE_JOURNEYPATTERN_MODAL' + }) + ).toEqual(Object.assign({}, state, { type: 'create' })) + }) + + it('should handle DELETE_JOURNEYPATTERN', () => { + expect( + modalReducer(state, { + type: 'DELETE_JOURNEYPATTERN', + index: 0 + }) + ).toEqual(state) + }) + + it('should handle SAVE_MODAL', () => { + expect( + modalReducer(state, { + type: 'SAVE_MODAL', + index: 0, + data: {} + }) + ).toEqual(state) + }) + + it('should handle CLOSE_MODAL', () => { + expect( + modalReducer(state, { + type: 'CLOSE_MODAL' + }) + ).toEqual(state) + }) +}) diff --git a/spec/javascripts/journey_patterns/reducers/pagination_spec.js b/spec/javascripts/journey_patterns/reducers/pagination_spec.js new file mode 100644 index 000000000..a99e8ff85 --- /dev/null +++ b/spec/javascripts/journey_patterns/reducers/pagination_spec.js @@ -0,0 +1,77 @@ +var reducer = require('es6_browserified/journey_patterns/reducers/pagination') +let state = { + page : 2, + totalCount : 25 +} +let currentPage = 2 +const dispatch = function(){} + +describe('pagination reducer, given parameters allowing page change', () => { + + it('should return the initial state', () => { + expect( + reducer(undefined, {}) + ).toEqual({}) + }) + + it('should handle GO_TO_NEXT_PAGE and change state', () => { + expect( + reducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + currentPage, + nextPage : true + }) + ).toEqual(Object.assign({}, state, {page : state.page + 1})) + }) + + it('should return GO_TO_PREVIOUS_PAGE and change state', () => { + expect( + reducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + currentPage, + nextPage : false + }) + ).toEqual(Object.assign({}, state, {page : state.page - 1})) + }) +}) + + +describe('pagination reducer, given parameters not allowing to go to previous page', () => { + + beforeEach(()=>{ + state.page = 1 + currentPage = 1 + }) + + it('should return GO_TO_PREVIOUS_PAGE and not change state', () => { + expect( + reducer(state, { + type: 'GO_TO_PREVIOUS_PAGE', + dispatch, + currentPage, + nextPage : false + }) + ).toEqual(state) + }) +}) + +describe('pagination reducer, given parameters not allowing to go to next page', () => { + + beforeEach(()=>{ + state.page = 3 + currentPage = 3 + }) + + it('should return GO_TO_NEXT_PAGE and not change state', () => { + expect( + reducer(state, { + type: 'GO_TO_NEXT_PAGE', + dispatch, + currentPage, + nextPage : false + }) + ).toEqual(state) + }) +}) diff --git a/spec/javascripts/spec_helper.js b/spec/javascripts/spec_helper.js index 71d30ff8d..a2fde3860 100644 --- a/spec/javascripts/spec_helper.js +++ b/spec/javascripts/spec_helper.js @@ -4,6 +4,7 @@ // require support/jasmine-jquery-2.1.0 // require support/sinon // require support/your-support-file +require('es6-object-assign').polyfill(); // // PhantomJS (Teaspoons default driver) doesn't have support for Function.prototype.bind, which has caused confusion. // Use this polyfill to avoid the confusion. diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb new file mode 100644 index 000000000..36981961f --- /dev/null +++ b/spec/models/calendar_spec.rb @@ -0,0 +1,148 @@ +require 'rails_helper' + +RSpec.describe Calendar, :type => :model do + + it { should belong_to(:organisation) } + + it { is_expected.to validate_presence_of(:organisation) } + it { is_expected.to validate_presence_of(:name) } + it { is_expected.to validate_presence_of(:short_name) } + it { is_expected.to validate_uniqueness_of(:short_name) } + + describe 'validations' do + it 'validates that dates and date_ranges do not overlap' do + calendar = build(:calendar, dates: [Date.today], date_ranges: [Date.today..Date.tomorrow]) + expect { + calendar.save! + }.to raise_error(ActiveRecord::RecordInvalid) + end + + it 'validates that there are no duplicates in dates' do + calendar = build(:calendar, dates: [Date.yesterday, Date.yesterday], date_ranges: [Date.today..Date.tomorrow]) + expect { + calendar.save! + }.to raise_error(ActiveRecord::RecordInvalid) + end + end + + describe 'Period' do + + subject { period } + + def period(attributes = {}) + return @period if attributes.empty? and @period + Calendar::Period.new(attributes).tap do |period| + @period = period if attributes.empty? + end + end + + it 'should support mark_for_destruction (required by cocoon)' do + period.mark_for_destruction + expect(period).to be_marked_for_destruction + end + + it 'should support _destroy attribute (required by coocon)' do + period._destroy = true + expect(period).to be_marked_for_destruction + end + + it 'should support new_record? (required by cocoon)' do + expect(Calendar::Period.new).to be_new_record + expect(period(id: 42)).not_to be_new_record + end + + it 'should cast begin as date attribute' do + expect(period(begin: '2016-11-22').begin).to eq(Date.new(2016,11,22)) + end + + it 'should cast end as date attribute' do + expect(period(end: '2016-11-22').end).to eq(Date.new(2016,11,22)) + end + + it { is_expected.to validate_presence_of(:begin) } + it { is_expected.to validate_presence_of(:end) } + + it 'should validate that end is greather than or equlals to begin' do + expect(period(begin: '2016-11-21', end: '2016-11-22')).to be_valid + expect(period(begin: '2016-11-21', end: '2016-11-21')).to be_valid + expect(period(begin: '2016-11-22', end: '2016-11-21')).to_not be_valid + end + + describe 'intersect?' do + + it 'should detect date in common with other date_ranges' do + november = period(begin: '2016-11-01', end: '2016-11-30') + mid_november_mid_december = period(begin: '2016-11-15', end: '2016-12-15') + expect(november.intersect?(mid_november_mid_december)).to be(true) + end + + it 'should not intersect when no date is in common' do + november = period(begin: '2016-11-01', end: '2016-11-30') + december = period(begin: '2016-12-01', end: '2016-12-31') + + expect(november.intersect?(december)).to be(false) + + january = period(begin: '2017-01-01', end: '2017-01-31') + expect(november.intersect?(december, january)).to be(false) + end + + it 'should not intersect itself' do + period = period(id: 42, begin: '2016-11-01', end: '2016-11-30') + expect(period.intersect?(period)).to be(false) + end + + end + end + + describe 'before_validation' do + let(:calendar) { create(:calendar, date_ranges: []) } + + it 'shoud fill date_ranges with date ranges' do + expected_ranges = [ + Range.new(Date.today, Date.tomorrow) + ] + expected_ranges.each_with_index do |range, index| + calendar.date_ranges << Calendar::Period.from_range(index, range) + end + calendar.valid? + + expect(calendar.date_ranges.map { |period| period.begin..period.end }).to eq(expected_ranges) + end + end + + describe 'DateValue' do + + subject { date_value } + + def date_value(attributes = {}) + return @date_value if attributes.empty? and @date_value + Calendar::DateValue.new(attributes).tap do |date_value| + @date_value = date_value if attributes.empty? + end + end + + it 'should support mark_for_destruction (required by cocoon)' do + date_value.mark_for_destruction + expect(date_value).to be_marked_for_destruction + end + + it 'should support _destroy attribute (required by coocon)' do + date_value._destroy = true + expect(date_value).to be_marked_for_destruction + end + + it 'should support new_record? (required by cocoon)' do + expect(Calendar::DateValue.new).to be_new_record + expect(date_value(id: 42)).not_to be_new_record + end + + it 'should cast value as date attribute' do + expect(date_value(value: '2017-01-03').value).to eq(Date.new(2017,01,03)) + end + + it { is_expected.to validate_presence_of(:value) } + + end + +end + diff --git a/spec/models/chouette/access_point_spec.rb b/spec/models/chouette/access_point_spec.rb index 41daca871..02b1621e3 100644 --- a/spec/models/chouette/access_point_spec.rb +++ b/spec/models/chouette/access_point_spec.rb @@ -10,7 +10,7 @@ describe Chouette::AccessPoint, :type => :model do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_numericality_of :latitude } it { is_expected.to validate_numericality_of :longitude } - + describe ".latitude" do it "should accept -90 value" do subject = create :access_point @@ -82,13 +82,13 @@ describe Chouette::AccessPoint, :type => :model do subject.latitude = nil expect(subject.valid?).to be_falsey end - end + end describe "#access_type" do def self.legacy_access_types %w{In Out InOut} end - + legacy_access_types.each do |access_type| context "when access_type is #{access_type}" do access_point_type = Chouette::AccessPointType.new(access_type.underscore) @@ -100,7 +100,7 @@ describe Chouette::AccessPoint, :type => :model do end end - describe "#access_point_type=" do + describe "#access_point_type=" do it "should change access_type with Chouette::AccessPointType#name" do subject.access_point_type = "in_out" expect(subject.access_type).to eq("InOut") @@ -109,7 +109,7 @@ describe Chouette::AccessPoint, :type => :model do end describe "#to_lat_lng" do - + it "should return nil if latitude is nil" do subject.latitude = nil expect(subject.to_lat_lng).to be_nil @@ -123,7 +123,7 @@ describe Chouette::AccessPoint, :type => :model do end describe "#geometry" do - + it "should be nil when to_lat_lng is nil" do allow(subject).to receive_messages :to_lat_lng => nil expect(subject.geometry).to be_nil @@ -133,75 +133,75 @@ describe Chouette::AccessPoint, :type => :model do describe "#generic_access_link_matrix" do it "should have 2 generic_access_links in matrix" do - stop_place = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place + stop_place = create :stop_area, :area_type => "zdlp" + commercial_stop_point = create :stop_area, :area_type => "lda" ,:parent => stop_place subject = create :access_point, :stop_area => stop_place expect(subject.generic_access_link_matrix.size).to eq(2) end - + it "should have new generic_access_links in matrix" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point subject.generic_access_link_matrix.each do |link| expect(link.id).to be_nil end end - it "should have only last generic_access_links as new in matrix" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" - subject = create :access_point, :stop_area => commercial_stop_point - link = create :access_link, :access_point => subject, :stop_area => commercial_stop_point - subject.generic_access_link_matrix.each do |link| - if link.link_key.start_with?"A_" - expect(link.id).not_to be_nil - else - expect(link.id).to be_nil - end - end - end + # it "should have only last generic_access_links as new in matrix" do + # commercial_stop_point = create :stop_area, :area_type => "lda" + # subject = create :access_point, :stop_area => commercial_stop_point + # link = create :access_link, :access_point => subject, :stop_area => commercial_stop_point + # subject.generic_access_link_matrix.each do |link| + # if link.link_key.start_with?"A_" + # expect(link.id).not_to be_nil + # else + # expect(link.id).to be_nil + # end + # end + # end end describe "#detail_access_link_matrix" do - it "should have 4 detail_access_links in matrix" do - stop_place = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place - quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - subject = create :access_point, :stop_area => stop_place - expect(subject.detail_access_link_matrix.size).to eq(4) - end - + # it "should have 4 detail_access_links in matrix" do + # stop_place = create :stop_area, :area_type => "zdlp" + # commercial_stop_point = create :stop_area, :area_type => "lda" ,:parent => stop_place + # zdep1 = create :stop_area, :parent => commercial_stop_point, :area_type => "zdep" + # zdep2 = create :stop_area, :parent => commercial_stop_point, :area_type => "zdep" + # subject = create :access_point, :stop_area => stop_place + # expect(subject.detail_access_link_matrix.size).to eq(4) + # end + it "should have new detail_access_links in matrix" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" - quay = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + commercial_stop_point = create :stop_area, :area_type => "lda" + zdep = create :stop_area, :parent => commercial_stop_point, :area_type => "zdep" subject = create :access_point, :stop_area => commercial_stop_point subject.detail_access_link_matrix.each do |link| expect(link.id).to be_nil end end it "should have only last detail_access_links as new in matrix" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" - quay = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + commercial_stop_point = create :stop_area, :area_type => "lda" + zdep = create :stop_area, :parent => commercial_stop_point, :area_type => "zdep" subject = create :access_point, :stop_area => commercial_stop_point - link = create :access_link, :access_point => subject, :stop_area => quay + link = create :access_link, :access_point => subject, :stop_area => zdep subject.detail_access_link_matrix.each do |link| - if link.link_key.start_with?"A_" + if link.link_key.start_with?"A_" expect(link.id).not_to be_nil else expect(link.id).to be_nil - end + end end end end describe "#coordinates" do it "should convert coordinates into latitude/longitude" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point, :coordinates => "45.123,120.456" expect(subject.longitude).to be_within(0.001).of(120.456) expect(subject.latitude).to be_within(0.001).of(45.123) end it "should set empty coordinates into nil latitude/longitude" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point, :coordinates => "45.123,120.456" expect(subject.longitude).to be_within(0.001).of(120.456) expect(subject.latitude).to be_within(0.001).of(45.123) @@ -211,17 +211,17 @@ describe Chouette::AccessPoint, :type => :model do expect(subject.latitude).to be_nil end it "should convert latitude/longitude into coordinates" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point, :longitude => 120.456, :latitude => 45.123 expect(subject.coordinates).to eq("45.123,120.456") end it "should convert nil latitude/longitude into empty coordinates" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point, :longitude => nil, :latitude => nil expect(subject.coordinates).to eq("") end it "should accept valid coordinates" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point, :coordinates => "45.123,120.456" expect(subject.valid?).to be_truthy subject.coordinates = "45.123, 120.456" @@ -240,7 +240,7 @@ describe Chouette::AccessPoint, :type => :model do expect(subject.valid?).to be_truthy end it "should accept valid coordinates on limits" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point, :coordinates => "90,180" expect(subject.valid?).to be_truthy subject.coordinates = "-90,-180" @@ -251,7 +251,7 @@ describe Chouette::AccessPoint, :type => :model do expect(subject.valid?).to be_truthy end it "should reject invalid coordinates" do - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" + commercial_stop_point = create :stop_area, :area_type => "lda" subject = create :access_point, :stop_area => commercial_stop_point subject.coordinates = ",12" expect(subject.valid?).to be_falsey @@ -265,5 +265,5 @@ describe Chouette::AccessPoint, :type => :model do expect(subject.valid?).to be_falsey end end - + end diff --git a/spec/models/chouette/area_type_spec.rb b/spec/models/chouette/area_type_spec.rb deleted file mode 100644 index 14902416b..000000000 --- a/spec/models/chouette/area_type_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'spec_helper' - -describe Chouette::AreaType, :type => :model do - - def mode(text_code = "test", numerical_code = nil) - numerical_code ||= 1 if text_code == "test" - Chouette::AreaType.new(text_code, numerical_code) - end - - describe "#to_i" do - - it "should return numerical code" do - expect(mode("test", 1).to_i).to eq(1) - end - - end - - it "should return true to #test? when text code is 'test'" do - expect(mode("test")).to be_test - end - - it "should be equal when text codes are identical" do - expect(mode("test",1)).to eq(mode("test", 2)) - end - - describe ".new" do - - it "should find numerical code from text code" do - expect(mode("boarding_position").to_i).to eq(0) - end - - it "should find text code from numerical code" do - expect(mode(0)).to eq("boarding_position") - end - - it "should accept another mode" do - expect(Chouette::AreaType.new(mode("test"))).to eq(mode("test")) - end - - end - - - describe ".all" do - - Chouette::AreaType.definitions.each do |text_code, numerical_code| - it "should include a AreaType #{text_code}" do - expect(Chouette::AreaType.all).to include(Chouette::AreaType.new(text_code)) - end - end - - end - -end diff --git a/spec/models/chouette/connection_link_spec.rb b/spec/models/chouette/connection_link_spec.rb index e76190bcf..5921bf581 100644 --- a/spec/models/chouette/connection_link_spec.rb +++ b/spec/models/chouette/connection_link_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper' describe Chouette::ConnectionLink, :type => :model do - let!(:quay) { create :stop_area, :area_type => "Quay" } - let!(:boarding_position) { create :stop_area, :area_type => "BoardingPosition" } - let!(:commercial_stop_point) { create :stop_area, :area_type => "CommercialStopPoint" } - let!(:stop_place) { create :stop_area, :area_type => "StopPlace" } - let!(:itl) { create :stop_area, :area_type => "ITL" } + let!(:quay) { create :stop_area, :area_type => "zdep" } + # let!(:boarding_position) { create :stop_area, :area_type => "BoardingPosition" } + let!(:commercial_stop_point) { create :stop_area, :area_type => "lda" } + let!(:stop_place) { create :stop_area, :area_type => "zdlp" } subject { create(:connection_link) } it { is_expected.to validate_uniqueness_of :objectid } @@ -22,7 +21,7 @@ describe Chouette::ConnectionLink, :type => :model do def self.legacy_link_types %w{Underground Mixed Overground} end - + legacy_link_types.each do |link_type| context "when link_type is #{link_type}" do connection_link_type = Chouette::ConnectionLinkType.new(link_type.underscore) @@ -42,19 +41,11 @@ describe Chouette::ConnectionLink, :type => :model do end describe "#connection_link_type=" do - + it "should change link_type with ConnectionLinkType#name" do subject.connection_link_type = "Test" expect(subject.link_type).to eq("Test") end end - - describe ".possible_areas" do - - it "should not find areas type ITL" do - expect(subject.possible_areas).not_to eq([itl]) - end - end - end diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb new file mode 100644 index 000000000..d991538ba --- /dev/null +++ b/spec/models/chouette/routing_constraint_zone_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe Chouette::RoutingConstraintZone, type: :model do + + subject { create(:routing_constraint_zone) } + + it { is_expected.to validate_presence_of :name } + it { is_expected.to validate_presence_of :stop_area_ids } + it { is_expected.to validate_presence_of :line_id } + # shoulda matcher to validate length of array ? + xit { is_expected.to validate_length_of(:stop_area_ids).is_at_least(2) } + +end diff --git a/spec/models/chouette/stop_area_spec.rb b/spec/models/chouette/stop_area_spec.rb index cdddb407d..84262eb98 100644 --- a/spec/models/chouette/stop_area_spec.rb +++ b/spec/models/chouette/stop_area_spec.rb @@ -1,11 +1,11 @@ require 'spec_helper' describe Chouette::StopArea, :type => :model do - let!(:quay) { create :stop_area, :area_type => "Quay" } - let!(:boarding_position) { create :stop_area, :area_type => "BoardingPosition" } - let!(:commercial_stop_point) { create :stop_area, :area_type => "CommercialStopPoint" } - let!(:stop_place) { create :stop_area, :area_type => "StopPlace" } - let!(:itl) { create :stop_area, :area_type => "ITL" } + # FIXME !!!!!!!! + let!(:quay) { create :stop_area, :area_type => "zdep" } + # let!(:boarding_position) { create :stop_area, :area_type => "BoardingPosition" } + let!(:commercial_stop_point) { create :stop_area, :area_type => "lda" } + let!(:stop_place) { create :stop_area, :area_type => "zdlp" } # Refs #1627 # describe '#objectid' do @@ -19,408 +19,398 @@ describe Chouette::StopArea, :type => :model do it { is_expected.to validate_numericality_of :longitude } - describe ".latitude" do - it "should accept -90 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.latitude = -90 - expect(subject.valid?).to be_truthy - end - it "should reject < -90 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.latitude = -90.0001 - expect(subject.valid?).to be_falsey - end - it "should accept 90 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.latitude = 90 - expect(subject.valid?).to be_truthy - end - it "should reject > 90 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.latitude = 90.0001 - expect(subject.valid?).to be_falsey - end - end - - describe ".longitude" do - it "should accept -180 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = -180 - expect(subject.valid?).to be_truthy - end - it "should reject < -180 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = -180.0001 - expect(subject.valid?).to be_falsey - end - it "should accept 180 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = 180 - expect(subject.valid?).to be_truthy - end - it "should reject > 180 value" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = 180.0001 - expect(subject.valid?).to be_falsey - end - end - - describe ".long_lat" do - it "should accept longitude and latitude both as nil" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = nil - subject.latitude = nil - expect(subject.valid?).to be_truthy - end - it "should accept longitude and latitude both numerical" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = 10 - subject.latitude = 10 - expect(subject.valid?).to be_truthy - end - it "should reject longitude nil with latitude numerical" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = nil - subject.latitude = 10 - expect(subject.valid?).to be_falsey - end - it "should reject longitude numerical with latitude nil" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.longitude = 10 - subject.latitude = nil - expect(subject.valid?).to be_falsey - end - end - - - describe ".children_in_depth" do - it "should return all the deepest children from stop area" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint", :parent => subject - commercial_stop_point2 = create :stop_area, :area_type => "CommercialStopPoint", :parent => commercial_stop_point - quay = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - expect(subject.children_in_depth).to match_array([commercial_stop_point, commercial_stop_point2, quay]) - end - it "should return only the deepest children from stop area" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint", :parent => subject - commercial_stop_point2 = create :stop_area, :area_type => "CommercialStopPoint", :parent => commercial_stop_point - quay = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - expect(subject.children_at_base).to match_array([quay]) - end - end - - describe ".stop_area_type" do - it "should have area_type of BoardingPosition when stop_area_type is set to boarding_position" do - subject = create :stop_area, :stop_area_type => "boarding_position" - expect(subject.area_type).to eq("BoardingPosition") - end - it "should have area_type of Quay when stop_area_type is set to quay" do - subject = create :stop_area, :stop_area_type => "quay" - expect(subject.area_type).to eq("Quay") - end - it "should have area_type of CommercialStopPoint when stop_area_type is set to commercial_stop_point" do - subject = create :stop_area, :stop_area_type => "commercial_stop_point" - expect(subject.area_type).to eq("CommercialStopPoint") - end - it "should have area_type of StopPlace when stop_area_type is set to stop_place" do - subject = create :stop_area, :stop_area_type => "stop_place" - expect(subject.area_type).to eq("StopPlace") - end - it "should have area_type of ITL when stop_area_type is set to itl" do - subject = create :stop_area, :stop_area_type => "itl" - expect(subject.area_type).to eq("ITL") - end - end - - describe ".parent" do - it "should check if parent method exists" do - subject = create :stop_area, :parent_id => commercial_stop_point.id - expect(subject.parent).to eq(commercial_stop_point) - end - end - - describe ".possible_children" do - - it "should find no possible descendant for stop area type quay" do - subject = create :stop_area, :area_type => "Quay" - expect(subject.possible_children).to eq([]) - end - - it "should find no possible descendant for stop area type boarding position" do - subject = create :stop_area, :area_type => "BoardingPosition" - expect(subject.possible_children).to eq([]) - end - - it "should find descendant of type quay or boarding position for stop area type commercial stop point" do - subject = create :stop_area, :area_type => "CommercialStopPoint" - expect(subject.possible_children).to match_array([quay, boarding_position]) - end - - it "should find no children of type stop place or commercial stop point for stop area type stop place" do - subject = create :stop_area, :area_type => "StopPlace" - expect(subject.possible_children).to match_array([stop_place, commercial_stop_point]) - end - - it "should find no children of type ITL for stop area type ITL" do - subject = create :stop_area, :area_type => "ITL" - expect(subject.possible_children).to match_array([stop_place, commercial_stop_point, quay, boarding_position]) - end - - end - - describe ".possible_parents" do - - it "should find parent type commercial stop point for stop area type boarding position" do - subject = create :stop_area, :area_type => "BoardingPosition" - expect(subject.possible_parents).to eq([commercial_stop_point]) - end - - it "should find parent type commercial stop point for stop area type quay" do - subject = create :stop_area, :area_type => "Quay" - expect(subject.possible_parents).to eq([commercial_stop_point]) - end - - it "should find parent type stop place for stop area type commercial stop point" do - subject = create :stop_area, :area_type => "CommercialStopPoint" - expect(subject.possible_parents).to eq([stop_place]) - end - - it "should find parent type stop place for stop area type stop place" do - subject = create :stop_area, :area_type => "StopPlace" - expect(subject.possible_parents).to eq([stop_place]) - end - - end - - - describe ".near" do - - let(:stop_area) { create :stop_area, :latitude => 1, :longitude => 1 } - let(:stop_area2) { create :stop_area, :latitude => 1, :longitude => 1 } - - it "should find a StopArea at 300m from given origin" do - expect(Chouette::StopArea.near(stop_area.to_lat_lng.endpoint(0, 0.250, :units => :kms))).to eq([stop_area]) - end - - it "should not find a StopArea at more than 300m from given origin" do - expect(Chouette::StopArea.near(stop_area2.to_lat_lng.endpoint(0, 0.350, :units => :kms))).to be_empty - end - - end - - describe "#to_lat_lng" do - - it "should return nil if latitude is nil" do - subject.latitude = nil - expect(subject.to_lat_lng).to be_nil - end - - it "should return nil if longitude is nil" do - subject.longitude = nil - expect(subject.to_lat_lng).to be_nil - end - - end - - describe "#geometry" do - - it "should be nil when to_lat_lng is nil" do - allow(subject).to receive_messages :to_lat_lng => nil - expect(subject.geometry).to be_nil - end - - end - - describe ".bounds" do - - it "should return transform coordinates in floats" do - allow(Chouette::StopArea.connection).to receive_messages :select_rows => [["113.5292500000000000", "22.1127580000000000", "113.5819330000000000", "22.2157050000000000"]] - expect(GeoRuby::SimpleFeatures::Envelope).to receive(:from_coordinates).with([[113.5292500000000000, 22.1127580000000000], [113.5819330000000000, 22.2157050000000000]]) - Chouette::StopArea.bounds - end - - end - - describe "#default_position" do - - # FIXME #821 - # it "should return referential center point when StopArea.bounds is nil" do - # allow(Chouette::StopArea).to receive_messages :bounds => nil - # expect(subject.default_position).not_to be_nil - # end - - it "should return StopArea.bounds center" do - allow(Chouette::StopArea).to receive_messages :bounds => double(:center => "center") - expect(subject.default_position).to eq(Chouette::StopArea.bounds.center) - end - - end - - describe "#children_at_base" do - it "should have 2 children_at_base" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject - quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - expect(subject.children_at_base.size).to eq(2) - end - end - - - describe "#generic_access_link_matrix" do - it "should have no access_links in matrix with no access_point" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject - expect(subject.generic_access_link_matrix.size).to eq(0) - end - it "should have 4 generic_access_links in matrix with 2 access_points" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject - access_point1 = create :access_point, :stop_area => subject - access_point2 = create :access_point, :stop_area => subject - expect(subject.generic_access_link_matrix.size).to eq(4) - end - end - describe "#detail_access_link_matrix" do - it "should have no access_links in matrix with no access_point" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject - quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - expect(subject.detail_access_link_matrix.size).to eq(0) - end - it "should have 8 detail_access_links in matrix with 2 children_at_base and 2 access_points" do - subject = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject - quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - access_point1 = create :access_point, :stop_area => subject - access_point2 = create :access_point, :stop_area => subject - expect(subject.detail_access_link_matrix.size).to eq(8) - end - end - describe "#parents" do - it "should return parent hireachy list" do - stop_place = create :stop_area, :area_type => "StopPlace" - commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place - subject = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" - expect(subject.parents.size).to eq(2) - end - it "should return empty parent hireachy list" do - subject = create :stop_area, :area_type => "Quay" - expect(subject.parents.size).to eq(0) - end - end - - describe "#clean_invalid_access_links" do - it "should remove invalid access links" do - # subject is a CSP with a SP as parent, a quay as child - # 2 access_points of SP have access_link, one on subject, one on subject child - # when detaching subject from SP, both access_links must be deleted - stop_place = create :stop_area, :area_type => "StopPlace" - subject = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place - access_point1 = create :access_point, :stop_area => stop_place - access_point2 = create :access_point, :stop_area => stop_place - quay = create :stop_area, :parent => subject, :area_type => "Quay" - access_link1 = create :access_link, :stop_area => subject, :access_point => access_point1 - access_link2 = create :access_link, :stop_area => quay, :access_point => access_point2 - subject.save - expect(subject.access_links.size).to eq(1) - expect(quay.access_links.size).to eq(1) - subject.parent=nil - subject.save - subject.reload - expect(subject.access_links.size).to eq(0) - expect(quay.access_links.size).to eq(0) - end - it "should not remove still valid access links" do - # subject is a Q of CSP with a SP as parent - # 2 access_points, one of SP, one of CSP have access_link on subject - # when changing subject CSP to another CSP of same SP - # one access_links must be kept - stop_place = create :stop_area, :area_type => "StopPlace" - commercial_stop_point1 = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place - commercial_stop_point2 = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place - access_point1 = create :access_point, :stop_area => stop_place - access_point2 = create :access_point, :stop_area => commercial_stop_point1 - subject = create :stop_area, :parent => commercial_stop_point1, :area_type => "Quay" - access_link1 = create :access_link, :stop_area => subject, :access_point => access_point1 - access_link2 = create :access_link, :stop_area => subject, :access_point => access_point2 - subject.save - expect(subject.access_links.size).to eq(2) - subject.parent=commercial_stop_point2 - subject.save - subject.reload - expect(subject.access_links.size).to eq(1) - end - end - - describe "#coordinates" do - it "should convert coordinates into latitude/longitude" do - subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "45.123,120.456" - expect(subject.longitude).to be_within(0.001).of(120.456) - expect(subject.latitude).to be_within(0.001).of(45.123) - end - it "should set empty coordinates into nil latitude/longitude" do - subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "45.123,120.456" - expect(subject.longitude).to be_within(0.001).of(120.456) - expect(subject.latitude).to be_within(0.001).of(45.123) - subject.coordinates = "" - subject.save - expect(subject.longitude).to be_nil - expect(subject.latitude).to be_nil - end - it "should convert latitude/longitude into coordinates" do - subject = create :stop_area, :area_type => "BoardingPosition", :longitude => 120.456, :latitude => 45.123 - expect(subject.coordinates).to eq("45.123,120.456") - end - it "should convert nil latitude/longitude into empty coordinates" do - subject = create :stop_area, :area_type => "BoardingPosition", :longitude => nil, :latitude => nil - expect(subject.coordinates).to eq("") - end - it "should accept valid coordinates" do - subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "45.123,120.456" - expect(subject.valid?).to be_truthy - subject.coordinates = "45.123, 120.456" - expect(subject.valid?).to be_truthy - expect(subject.longitude).to be_within(0.001).of(120.456) - expect(subject.latitude).to be_within(0.001).of(45.123) - subject.coordinates = "45.123, -120.456" - expect(subject.valid?).to be_truthy - subject.coordinates = "45.123 ,120.456" - expect(subject.valid?).to be_truthy - subject.coordinates = "45.123 , 120.456" - expect(subject.valid?).to be_truthy - subject.coordinates = " 45.123,120.456" - expect(subject.valid?).to be_truthy - subject.coordinates = "45.123,120.456 " - expect(subject.valid?).to be_truthy - end - it "should accept valid coordinates on limits" do - subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "90,180" - expect(subject.valid?).to be_truthy - subject.coordinates = "-90,-180" - expect(subject.valid?).to be_truthy - subject.coordinates = "-90.,180." - expect(subject.valid?).to be_truthy - subject.coordinates = "-90.0,180.00" - expect(subject.valid?).to be_truthy - end - it "should reject invalid coordinates" do - subject = create :stop_area, :area_type => "BoardingPosition" - subject.coordinates = ",12" - expect(subject.valid?).to be_falsey - subject.coordinates = "-90" - expect(subject.valid?).to be_falsey - subject.coordinates = "-90.1,180." - expect(subject.valid?).to be_falsey - subject.coordinates = "-90.0,180.1" - expect(subject.valid?).to be_falsey - subject.coordinates = "-91.0,18.1" - expect(subject.valid?).to be_falsey - end - end + # describe ".latitude" do + # it "should accept -90 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.latitude = -90 + # expect(subject.valid?).to be_truthy + # end + # it "should reject < -90 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.latitude = -90.0001 + # expect(subject.valid?).to be_falsey + # end + # it "should accept 90 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.latitude = 90 + # expect(subject.valid?).to be_truthy + # end + # it "should reject > 90 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.latitude = 90.0001 + # expect(subject.valid?).to be_falsey + # end + # end + + # describe ".longitude" do + # it "should accept -180 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = -180 + # expect(subject.valid?).to be_truthy + # end + # it "should reject < -180 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = -180.0001 + # expect(subject.valid?).to be_falsey + # end + # it "should accept 180 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = 180 + # expect(subject.valid?).to be_truthy + # end + # it "should reject > 180 value" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = 180.0001 + # expect(subject.valid?).to be_falsey + # end + # end + + # describe ".long_lat" do + # it "should accept longitude and latitude both as nil" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = nil + # subject.latitude = nil + # expect(subject.valid?).to be_truthy + # end + # it "should accept longitude and latitude both numerical" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = 10 + # subject.latitude = 10 + # expect(subject.valid?).to be_truthy + # end + # it "should reject longitude nil with latitude numerical" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = nil + # subject.latitude = 10 + # expect(subject.valid?).to be_falsey + # end + # it "should reject longitude numerical with latitude nil" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.longitude = 10 + # subject.latitude = nil + # expect(subject.valid?).to be_falsey + # end + # end + + + # describe ".children_in_depth" do + # it "should return all the deepest children from stop area" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint", :parent => subject + # commercial_stop_point2 = create :stop_area, :area_type => "CommercialStopPoint", :parent => commercial_stop_point + # quay = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # expect(subject.children_in_depth).to match_array([commercial_stop_point, commercial_stop_point2, quay]) + # end + # it "should return only the deepest children from stop area" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint", :parent => subject + # commercial_stop_point2 = create :stop_area, :area_type => "CommercialStopPoint", :parent => commercial_stop_point + # quay = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # expect(subject.children_at_base).to match_array([quay]) + # end + # end + + # describe ".stop_area_type" do + # it "should have area_type of BoardingPosition when stop_area_type is set to boarding_position" do + # subject = create :stop_area, :stop_area_type => "boarding_position" + # expect(subject.area_type).to eq("BoardingPosition") + # end + # it "should have area_type of Quay when stop_area_type is set to quay" do + # subject = create :stop_area, :stop_area_type => "quay" + # expect(subject.area_type).to eq("Quay") + # end + # it "should have area_type of CommercialStopPoint when stop_area_type is set to commercial_stop_point" do + # subject = create :stop_area, :stop_area_type => "commercial_stop_point" + # expect(subject.area_type).to eq("CommercialStopPoint") + # end + # it "should have area_type of StopPlace when stop_area_type is set to stop_place" do + # subject = create :stop_area, :stop_area_type => "stop_place" + # expect(subject.area_type).to eq("StopPlace") + # end + # end + + # describe ".parent" do + # it "should check if parent method exists" do + # subject = create :stop_area, :parent_id => commercial_stop_point.id + # expect(subject.parent).to eq(commercial_stop_point) + # end + # end + + # describe ".possible_children" do + + # it "should find no possible descendant for stop area type quay" do + # subject = create :stop_area, :area_type => "Quay" + # expect(subject.possible_children).to eq([]) + # end + + # it "should find no possible descendant for stop area type boarding position" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # expect(subject.possible_children).to eq([]) + # end + + # it "should find descendant of type quay or boarding position for stop area type commercial stop point" do + # subject = create :stop_area, :area_type => "CommercialStopPoint" + # expect(subject.possible_children).to match_array([quay, boarding_position]) + # end + + # it "should find no children of type stop place or commercial stop point for stop area type stop place" do + # subject = create :stop_area, :area_type => "StopPlace" + # expect(subject.possible_children).to match_array([stop_place, commercial_stop_point]) + # end + # end + + # describe ".possible_parents" do + + # it "should find parent type commercial stop point for stop area type boarding position" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # expect(subject.possible_parents).to eq([commercial_stop_point]) + # end + + # it "should find parent type commercial stop point for stop area type quay" do + # subject = create :stop_area, :area_type => "Quay" + # expect(subject.possible_parents).to eq([commercial_stop_point]) + # end + + # it "should find parent type stop place for stop area type commercial stop point" do + # subject = create :stop_area, :area_type => "CommercialStopPoint" + # expect(subject.possible_parents).to eq([stop_place]) + # end + + # it "should find parent type stop place for stop area type stop place" do + # subject = create :stop_area, :area_type => "StopPlace" + # expect(subject.possible_parents).to eq([stop_place]) + # end + + # end + + + # describe ".near" do + + # let(:stop_area) { create :stop_area, :latitude => 1, :longitude => 1 } + # let(:stop_area2) { create :stop_area, :latitude => 1, :longitude => 1 } + + # it "should find a StopArea at 300m from given origin" do + # expect(Chouette::StopArea.near(stop_area.to_lat_lng.endpoint(0, 0.250, :units => :kms))).to eq([stop_area]) + # end + + # it "should not find a StopArea at more than 300m from given origin" do + # expect(Chouette::StopArea.near(stop_area2.to_lat_lng.endpoint(0, 0.350, :units => :kms))).to be_empty + # end + + # end + + # describe "#to_lat_lng" do + + # it "should return nil if latitude is nil" do + # subject.latitude = nil + # expect(subject.to_lat_lng).to be_nil + # end + + # it "should return nil if longitude is nil" do + # subject.longitude = nil + # expect(subject.to_lat_lng).to be_nil + # end + + # end + + # describe "#geometry" do + + # it "should be nil when to_lat_lng is nil" do + # allow(subject).to receive_messages :to_lat_lng => nil + # expect(subject.geometry).to be_nil + # end + + # end + + # describe ".bounds" do + + # it "should return transform coordinates in floats" do + # allow(Chouette::StopArea.connection).to receive_messages :select_rows => [["113.5292500000000000", "22.1127580000000000", "113.5819330000000000", "22.2157050000000000"]] + # expect(GeoRuby::SimpleFeatures::Envelope).to receive(:from_coordinates).with([[113.5292500000000000, 22.1127580000000000], [113.5819330000000000, 22.2157050000000000]]) + # Chouette::StopArea.bounds + # end + + # end + + # describe "#default_position" do + + # # FIXME #821 + # # it "should return referential center point when StopArea.bounds is nil" do + # # allow(Chouette::StopArea).to receive_messages :bounds => nil + # # expect(subject.default_position).not_to be_nil + # # end + + # it "should return StopArea.bounds center" do + # allow(Chouette::StopArea).to receive_messages :bounds => double(:center => "center") + # expect(subject.default_position).to eq(Chouette::StopArea.bounds.center) + # end + + # end + + # describe "#children_at_base" do + # it "should have 2 children_at_base" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject + # quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # expect(subject.children_at_base.size).to eq(2) + # end + # end + + + # describe "#generic_access_link_matrix" do + # it "should have no access_links in matrix with no access_point" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject + # expect(subject.generic_access_link_matrix.size).to eq(0) + # end + # it "should have 4 generic_access_links in matrix with 2 access_points" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject + # access_point1 = create :access_point, :stop_area => subject + # access_point2 = create :access_point, :stop_area => subject + # expect(subject.generic_access_link_matrix.size).to eq(4) + # end + # end + # describe "#detail_access_link_matrix" do + # it "should have no access_links in matrix with no access_point" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject + # quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # expect(subject.detail_access_link_matrix.size).to eq(0) + # end + # it "should have 8 detail_access_links in matrix with 2 children_at_base and 2 access_points" do + # subject = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => subject + # quay1 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # quay2 = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # access_point1 = create :access_point, :stop_area => subject + # access_point2 = create :access_point, :stop_area => subject + # expect(subject.detail_access_link_matrix.size).to eq(8) + # end + # end + # describe "#parents" do + # it "should return parent hireachy list" do + # stop_place = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place + # subject = create :stop_area, :parent => commercial_stop_point, :area_type => "Quay" + # expect(subject.parents.size).to eq(2) + # end + # it "should return empty parent hireachy list" do + # subject = create :stop_area, :area_type => "Quay" + # expect(subject.parents.size).to eq(0) + # end + # end + + # describe "#clean_invalid_access_links" do + # it "should remove invalid access links" do + # # subject is a CSP with a SP as parent, a quay as child + # # 2 access_points of SP have access_link, one on subject, one on subject child + # # when detaching subject from SP, both access_links must be deleted + # stop_place = create :stop_area, :area_type => "StopPlace" + # subject = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place + # access_point1 = create :access_point, :stop_area => stop_place + # access_point2 = create :access_point, :stop_area => stop_place + # quay = create :stop_area, :parent => subject, :area_type => "Quay" + # access_link1 = create :access_link, :stop_area => subject, :access_point => access_point1 + # access_link2 = create :access_link, :stop_area => quay, :access_point => access_point2 + # subject.save + # expect(subject.access_links.size).to eq(1) + # expect(quay.access_links.size).to eq(1) + # subject.parent=nil + # subject.save + # subject.reload + # expect(subject.access_links.size).to eq(0) + # expect(quay.access_links.size).to eq(0) + # end + # it "should not remove still valid access links" do + # # subject is a Q of CSP with a SP as parent + # # 2 access_points, one of SP, one of CSP have access_link on subject + # # when changing subject CSP to another CSP of same SP + # # one access_links must be kept + # stop_place = create :stop_area, :area_type => "StopPlace" + # commercial_stop_point1 = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place + # commercial_stop_point2 = create :stop_area, :area_type => "CommercialStopPoint" ,:parent => stop_place + # access_point1 = create :access_point, :stop_area => stop_place + # access_point2 = create :access_point, :stop_area => commercial_stop_point1 + # subject = create :stop_area, :parent => commercial_stop_point1, :area_type => "Quay" + # access_link1 = create :access_link, :stop_area => subject, :access_point => access_point1 + # access_link2 = create :access_link, :stop_area => subject, :access_point => access_point2 + # subject.save + # expect(subject.access_links.size).to eq(2) + # subject.parent=commercial_stop_point2 + # subject.save + # subject.reload + # expect(subject.access_links.size).to eq(1) + # end + # end + + # describe "#coordinates" do + # it "should convert coordinates into latitude/longitude" do + # subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "45.123,120.456" + # expect(subject.longitude).to be_within(0.001).of(120.456) + # expect(subject.latitude).to be_within(0.001).of(45.123) + # end + # it "should set empty coordinates into nil latitude/longitude" do + # subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "45.123,120.456" + # expect(subject.longitude).to be_within(0.001).of(120.456) + # expect(subject.latitude).to be_within(0.001).of(45.123) + # subject.coordinates = "" + # subject.save + # expect(subject.longitude).to be_nil + # expect(subject.latitude).to be_nil + # end + # it "should convert latitude/longitude into coordinates" do + # subject = create :stop_area, :area_type => "BoardingPosition", :longitude => 120.456, :latitude => 45.123 + # expect(subject.coordinates).to eq("45.123,120.456") + # end + # it "should convert nil latitude/longitude into empty coordinates" do + # subject = create :stop_area, :area_type => "BoardingPosition", :longitude => nil, :latitude => nil + # expect(subject.coordinates).to eq("") + # end + # it "should accept valid coordinates" do + # subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "45.123,120.456" + # expect(subject.valid?).to be_truthy + # subject.coordinates = "45.123, 120.456" + # expect(subject.valid?).to be_truthy + # expect(subject.longitude).to be_within(0.001).of(120.456) + # expect(subject.latitude).to be_within(0.001).of(45.123) + # subject.coordinates = "45.123, -120.456" + # expect(subject.valid?).to be_truthy + # subject.coordinates = "45.123 ,120.456" + # expect(subject.valid?).to be_truthy + # subject.coordinates = "45.123 , 120.456" + # expect(subject.valid?).to be_truthy + # subject.coordinates = " 45.123,120.456" + # expect(subject.valid?).to be_truthy + # subject.coordinates = "45.123,120.456 " + # expect(subject.valid?).to be_truthy + # end + # it "should accept valid coordinates on limits" do + # subject = create :stop_area, :area_type => "BoardingPosition", :coordinates => "90,180" + # expect(subject.valid?).to be_truthy + # subject.coordinates = "-90,-180" + # expect(subject.valid?).to be_truthy + # subject.coordinates = "-90.,180." + # expect(subject.valid?).to be_truthy + # subject.coordinates = "-90.0,180.00" + # expect(subject.valid?).to be_truthy + # end + # it "should reject invalid coordinates" do + # subject = create :stop_area, :area_type => "BoardingPosition" + # subject.coordinates = ",12" + # expect(subject.valid?).to be_falsey + # subject.coordinates = "-90" + # expect(subject.valid?).to be_falsey + # subject.coordinates = "-90.1,180." + # expect(subject.valid?).to be_falsey + # subject.coordinates = "-90.0,180.1" + # expect(subject.valid?).to be_falsey + # subject.coordinates = "-91.0,18.1" + # expect(subject.valid?).to be_falsey + # end + # end # Refs #1627 # describe "#duplicate" do diff --git a/spec/policies/referential_policy_spec.rb b/spec/policies/referential_policy_spec.rb new file mode 100644 index 000000000..084ecc9f0 --- /dev/null +++ b/spec/policies/referential_policy_spec.rb @@ -0,0 +1,4 @@ +require 'rails_helper' + +RSpec.describe ReferentialPolicy do +end diff --git a/spec/tasks/reflex_rake_spec.rb b/spec/tasks/reflex_rake_spec.rb index 7a27b49fc..ab1aefc7d 100644 --- a/spec/tasks/reflex_rake_spec.rb +++ b/spec/tasks/reflex_rake_spec.rb @@ -31,7 +31,7 @@ describe 'reflex:sync' do it 'should map xml data to StopArea attribute' do stop_area = Chouette::StopArea.find_by(objectid: 'FR:77153:LDA:69325:STIF') expect(stop_area.zip_code).to eq '77153' - expect(stop_area.area_type).to eq 'StopPlace' + expect(stop_area.area_type).to eq 'lda' end context 'On next sync' do diff --git a/spec/views/companies/index.html.erb_spec.rb b/spec/views/companies/index.html.erb_spec.rb index 43981ac87..9db689ba6 100644 --- a/spec/views/companies/index.html.erb_spec.rb +++ b/spec/views/companies/index.html.erb_spec.rb @@ -16,9 +16,10 @@ RSpec.describe "/companies/index", :type => :view do # end # end - it "should render a link to create a new group" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_company_path(line_referential)}']") - end + # Fixme #1795 @see CompanyPolicy + # it "should render a link to create a new group" do + # render + # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_company_path(line_referential)}']") + # end end diff --git a/spec/views/lines/index.html.erb_spec.rb b/spec/views/lines/index.html.erb_spec.rb index 494f58040..dbc3cbdb7 100644 --- a/spec/views/lines/index.html.erb_spec.rb +++ b/spec/views/lines/index.html.erb_spec.rb @@ -12,16 +12,16 @@ describe "/lines/index", :type => :view do allow(view).to receive(:link_with_search).and_return("#") end - it "should render a show link for each group" do - render - lines.each do |line| - expect(rendered).to have_selector(".line a[href='#{view.line_referential_line_path(line_referential, line)}']", :text => line.name) - end - end - - it "should render a link to create a new group" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_line_path(line_referential)}']") - end + # it "should render a show link for each group" do + # render + # lines.each do |line| + # expect(rendered).to have_selector(".line a[href='#{view.line_referential_line_path(line_referential, line)}']", :text => line.name) + # end + # end + # + # it "should render a link to create a new group" do + # render + # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_line_path(line_referential)}']") + # end end diff --git a/spec/views/networks/index.html.erb_spec.rb b/spec/views/networks/index.html.erb_spec.rb index 2aef66920..d2dde7f87 100644 --- a/spec/views/networks/index.html.erb_spec.rb +++ b/spec/views/networks/index.html.erb_spec.rb @@ -6,16 +6,17 @@ describe "/networks/index", :type => :view do let!(:networks) { assign :networks, Array.new(2){ create(:network, line_referential: line_referential) }.paginate } let!(:search) { assign :q, Ransack::Search.new(Chouette::Network) } - it "should render a show link for each group" do - render - networks.each do |network| - expect(rendered).to have_selector(".network a[href='#{view.line_referential_network_path(line_referential, network)}']", :text => network.name) - end - end - - it "should render a link to create a new group" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_network_path(line_referential)}']") - end + # it "should render a show link for each group" do + # puts networks.inspect + # render + # networks.each do |network| + # expect(rendered).to have_selector("a[href='#{view.line_referential_network_path(line_referential, network)}']") + # end + # end + # + # it "should render a link to create a new group" do + # render + # expect(view.content_for(:sidebar)).to have_selector("a[href='#{new_line_referential_network_path(line_referential)}']") + # end end diff --git a/spec/views/stop_areas/index.html.erb_spec.rb b/spec/views/stop_areas/index.html.erb_spec.rb index 1886b49bb..2dfae1bfd 100644 --- a/spec/views/stop_areas/index.html.erb_spec.rb +++ b/spec/views/stop_areas/index.html.erb_spec.rb @@ -10,16 +10,16 @@ describe "/stop_areas/index", :type => :view do allow(view).to receive(:link_with_search).and_return("#") end - it "should render a show link for each group" do - render - stop_areas.each do |stop_area| - expect(rendered).to have_selector(".stop_area a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", :text => stop_area.name) - end - end - - it "should render a link to create a new group" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_stop_area_referential_stop_area_path(stop_area_referential)}']") - end + # it "should render a show link for each group" do + # render + # stop_areas.each do |stop_area| + # expect(rendered).to have_selector(".stop_area a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", :text => stop_area.name) + # end + # end + # + # it "should render a link to create a new group" do + # render + # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_stop_area_referential_stop_area_path(stop_area_referential)}']") + # end end diff --git a/spec/views/time_tables/new.html.erb_spec.rb b/spec/views/time_tables/new.html.erb_spec.rb index ee55a3322..6053d9862 100644 --- a/spec/views/time_tables/new.html.erb_spec.rb +++ b/spec/views/time_tables/new.html.erb_spec.rb @@ -4,8 +4,12 @@ describe "/time_tables/new", :type => :view do assign_referential let!(:time_table) { assign(:time_table, build(:time_table)) } + before do + allow(view).to receive_messages(current_organisation: referential.organisation) + end + describe "form" do - + it "should render input for comment" do render expect(rendered).to have_selector("form") do |
