diff --git a/Capfile b/Capfile index 1a33b63f0..ea11eb9b6 100644 --- a/Capfile +++ b/Capfile @@ -12,6 +12,10 @@ require 'capistrano/delayed_job' require 'whenever/capistrano' require 'rvm1/capistrano3' +#SCM: Git +require "capistrano/scm/git" +install_plugin Capistrano::SCM::Git + # Load custom tasks from `lib/capistrano/tasks` if you have any defined Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } diff --git a/Gemfile b/Gemfile index 13a0b3567..f9c2f54e5 100644 --- a/Gemfile +++ b/Gemfile @@ -1,20 +1,20 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.2.7.1' +gem 'rails', '4.2.8' # Use PostgreSQL -gem 'pg', '~> 0.19.0' +gem 'pg', '~> 0.20.0' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0', '>= 5.0.4' # Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '>= 3.0.4' +gem 'uglifier', '~> 3.1.9' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2.1' # See https://github.com/rails/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library -gem 'jquery-rails', '~> 4.2.2' +gem 'jquery-rails', '~> 4.3.1' gem 'jquery-ui-rails' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks gem 'turbolinks' @@ -28,10 +28,10 @@ gem 'devise_security_extension' # gem 'bcrypt', '~> 3.1.7' gem 'omniauth' gem 'omniauth-twitter' -gem 'omniauth-facebook', '~> 3.0.0' +gem 'omniauth-facebook', '~> 4.0.0' gem 'omniauth-google-oauth2', '~> 0.4.0' -gem 'kaminari' +gem 'kaminari', '~> 1.0.1' gem 'ancestry', '~> 2.2.2' gem 'acts-as-taggable-on' gem 'responders', '~> 2.3.0' @@ -40,30 +40,30 @@ gem 'foundation_rails_helper', '~> 2.0.0' gem 'acts_as_votable' gem 'ckeditor', '~> 4.2.2' gem 'invisible_captcha', '~> 0.9.2' -gem 'cancancan' -gem 'social-share-button' +gem 'cancancan', '~> 1.16.0' +gem 'social-share-button', '~> 0.10' gem 'initialjs-rails', '0.2.0.4' gem 'unicorn', '~> 5.2.0' -gem 'paranoia', '~> 2.2.0' +gem 'paranoia', '~> 2.2.1' gem 'rinku', '~> 2.0.2', require: 'rails_rinku' gem 'savon' gem 'dalli' -gem 'rollbar', '~> 2.14.0' +gem 'rollbar', '~> 2.14.1' gem 'delayed_job_active_record', '~> 4.1.0' gem 'daemons' gem 'devise-async' -gem 'newrelic_rpm', '~> 3.17.2.327' +gem 'newrelic_rpm', '~> 4.0.0.332' gem 'whenever', require: false gem 'pg_search' -gem 'sitemap_generator' +gem 'sitemap_generator', '~> 5.3.1' -gem 'ahoy_matey', '~> 1.5.3' -gem 'groupdate', '~> 3.1.0' # group temporary data +gem 'ahoy_matey', '~> 1.5.5' +gem 'groupdate', '~> 3.2.0' # group temporary data gem 'tolk', '~> 2.0.0' # Web interface for translations gem 'browser' gem 'turnout', '~> 2.4.0' -gem 'redcarpet' +gem 'redcarpet', '~> 3.4.0' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console @@ -72,28 +72,28 @@ group :development, :test do gem 'spring' gem 'spring-commands-rspec' gem 'rspec-rails', '~> 3.5' - gem 'capybara' - gem 'factory_girl_rails' + gem 'capybara', '~> 2.13.0' + gem 'factory_girl_rails', '~> 4.8.0' gem 'fuubar' gem 'launchy' gem 'quiet_assets' - gem 'letter_opener_web', '~> 1.3.0' - gem 'i18n-tasks' - gem 'capistrano', '3.5.0', require: false + gem 'letter_opener_web', '~> 1.3.1' + gem 'i18n-tasks', '~> 0.9.12' + gem 'capistrano', '~> 3.8.0', require: false gem 'capistrano-bundler', '~> 1.2', require: false - gem "capistrano-rails", '1.1.8', require: false + gem "capistrano-rails", '~> 1.2.3', require: false gem 'rvm1-capistrano3', require: false - gem 'capistrano3-delayed-job', '~> 1.0' - gem "bullet" - gem "faker" - gem 'rubocop', '~> 0.45.0', require: false + gem 'capistrano3-delayed-job', '~> 1.7.3' + gem "bullet", '~> 5.5.1' + gem "faker", '~> 1.7.3' + gem 'rubocop', '~> 0.47.1', require: false gem 'knapsack' end group :test do gem 'database_cleaner' - gem 'poltergeist' - gem 'coveralls', require: false + gem 'poltergeist', '~> 1.14.0' + gem 'coveralls', '~> 0.8.19', require: false gem 'email_spec' end diff --git a/Gemfile.lock b/Gemfile.lock index e2c21605c..6c117ea77 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,46 +1,46 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) + actionmailer (4.2.8) + actionpack (= 4.2.8) + actionview (= 4.2.8) + activejob (= 4.2.8) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.7.1) - actionview (= 4.2.7.1) - activesupport (= 4.2.7.1) + actionpack (4.2.8) + actionview (= 4.2.8) + activesupport (= 4.2.8) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.7.1) - activesupport (= 4.2.7.1) + actionview (4.2.8) + activesupport (= 4.2.8) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - activejob (4.2.7.1) - activesupport (= 4.2.7.1) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (4.2.8) + activesupport (= 4.2.8) globalid (>= 0.3.0) - activemodel (4.2.7.1) - activesupport (= 4.2.7.1) + activemodel (4.2.8) + activesupport (= 4.2.8) builder (~> 3.1) - activerecord (4.2.7.1) - activemodel (= 4.2.7.1) - activesupport (= 4.2.7.1) + activerecord (4.2.8) + activemodel (= 4.2.8) + activesupport (= 4.2.8) arel (~> 6.0) - activesupport (4.2.7.1) + activesupport (4.2.8) i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - acts-as-taggable-on (3.5.0) - activerecord (>= 3.2, < 5) + acts-as-taggable-on (4.0.0) + activerecord (>= 4.0) acts_as_votable (0.10.0) - addressable (2.4.0) - ahoy_matey (1.5.3) + addressable (2.5.0) + public_suffix (~> 2.0, >= 2.0.2) + ahoy_matey (1.5.5) addressable browser (~> 2.0) geocoder @@ -51,14 +51,14 @@ GEM safely_block (>= 0.1.1) user_agent_parser uuidtools - airbrussh (1.1.1) + airbrussh (1.1.2) sshkit (>= 1.6.1, != 1.7.0) akami (1.3.1) gyoku (>= 0.4.0) nokogiri ancestry (2.2.2) activerecord (>= 3.0.0) - arel (6.0.3) + arel (6.0.4) ast (2.3.0) babel-source (5.8.35) babel-transpiler (0.7.0) @@ -66,28 +66,27 @@ GEM execjs (~> 2.0) bcrypt (3.1.11) browser (2.3.0) - builder (3.2.2) - bullet (5.4.2) + builder (3.2.3) + bullet (5.5.1) activesupport (>= 3.0.0) uniform_notifier (~> 1.10.0) byebug (9.0.6) - cancancan (1.15.0) - capistrano (3.5.0) + cancancan (1.16.0) + capistrano (3.8.0) airbrussh (>= 1.0.0) - capistrano-harrow i18n rake (>= 10.0.0) sshkit (>= 1.9.0) capistrano-bundler (1.2.0) capistrano (~> 3.1) sshkit (~> 1.2) - capistrano-harrow (0.5.3) - capistrano-rails (1.1.8) + capistrano-rails (1.2.3) capistrano (~> 3.1) capistrano-bundler (~> 1.1) - capistrano3-delayed-job (1.7.2) + capistrano3-delayed-job (1.7.3) capistrano (~> 3.0, >= 3.0.0) - capybara (2.7.1) + daemons (~> 1.2.4) + capybara (2.13.0) addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -109,9 +108,9 @@ GEM coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.10.0) - concurrent-ruby (1.0.4) - coveralls (0.8.17) + coffee-script-source (1.12.2) + concurrent-ruby (1.0.5) + coveralls (0.8.19) json (>= 1.8, < 3) simplecov (~> 0.12.0) term-ansicolor (~> 1.3) @@ -151,14 +150,14 @@ GEM errbase (0.0.3) erubis (2.7.0) execjs (2.7.0) - factory_girl (4.7.0) + factory_girl (4.8.0) activesupport (>= 3.0.0) - factory_girl_rails (4.7.0) - factory_girl (~> 4.7.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) railties (>= 3.0.0) - faker (1.6.6) + faker (1.7.3) i18n (~> 0.5) - faraday (0.9.2) + faraday (0.11.0) multipart-post (>= 1.2, < 3) foundation-rails (6.2.4.0) railties (>= 3.1.0) @@ -173,20 +172,20 @@ GEM fuubar (2.2.0) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) - geocoder (1.4.1) + geocoder (1.4.3) globalid (0.3.7) activesupport (>= 4.1.0) - groupdate (3.1.1) + groupdate (3.2.0) activesupport (>= 3) gyoku (1.3.1) builder (>= 2.1.2) - hashie (3.4.6) + hashie (3.5.5) highline (1.7.8) htmlentities (4.3.4) httpi (2.4.1) rack - i18n (0.7.0) - i18n-tasks (0.9.6) + i18n (0.8.1) + i18n-tasks (0.9.12) activesupport (>= 4.0.2) ast (>= 2.1.0) easy_translate (>= 0.5.0) @@ -200,26 +199,35 @@ GEM railties (>= 3.1, < 6.0) invisible_captcha (0.9.2) rails (>= 3.2.0) - jquery-rails (4.2.2) + jquery-rails (4.3.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (5.0.5) + jquery-ui-rails (6.0.1) railties (>= 3.2.16) - json (1.8.3) - jwt (1.5.4) - kaminari (0.17.0) - actionpack (>= 3.0.0) - activesupport (>= 3.0.0) + json (2.0.3) + jwt (1.5.6) + kaminari (1.0.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.0.1) + kaminari-activerecord (= 1.0.1) + kaminari-core (= 1.0.1) + kaminari-actionview (1.0.1) + actionview + kaminari-core (= 1.0.1) + kaminari-activerecord (1.0.1) + activerecord + kaminari-core (= 1.0.1) + kaminari-core (1.0.1) kgio (2.11.0) - knapsack (1.13.1) + knapsack (1.13.2) rake timecop (>= 0.1.0) launchy (2.4.3) addressable (~> 2.3) letter_opener (1.4.1) launchy (~> 2.2) - letter_opener_web (1.3.0) + letter_opener_web (1.3.1) actionmailer (>= 3.2) letter_opener (~> 1.0) railties (>= 3.2) @@ -233,26 +241,26 @@ GEM mini_portile2 (2.1.0) minitest (5.10.1) multi_json (1.12.1) - multi_xml (0.5.5) + multi_xml (0.6.0) multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (3.2.0) - newrelic_rpm (3.17.2.327) - nokogiri (1.6.8.1) + net-ssh (4.1.0) + newrelic_rpm (4.0.0.332) + nokogiri (1.7.1) mini_portile2 (~> 2.1.0) nori (2.6.0) - oauth (0.5.0) - oauth2 (1.0.0) - faraday (>= 0.8, < 0.10) + oauth (0.5.1) + oauth2 (1.3.1) + faraday (>= 0.8, < 0.12) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) - rack (~> 1.2) - omniauth (1.3.1) - hashie (>= 1.2, < 4) - rack (>= 1.0, < 3) - omniauth-facebook (3.0.0) + rack (>= 1.2, < 3) + omniauth (1.6.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) + omniauth-facebook (4.0.0) omniauth-oauth2 (~> 1.2) omniauth-google-oauth2 (0.4.1) jwt (~> 1.5.2) @@ -265,24 +273,25 @@ GEM omniauth-oauth2 (1.4.0) oauth2 (~> 1.0) omniauth (~> 1.2) - omniauth-twitter (1.2.1) - json (~> 1.3) + omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) + rack orm_adapter (0.5.0) - paranoia (2.2.0) + paranoia (2.2.1) activerecord (>= 4.0, < 5.1) - parser (2.3.3.1) + parser (2.4.0.0) ast (~> 2.2) - pg (0.19.0) - pg_search (1.0.6) - activerecord (>= 3.1) - activesupport (>= 3.1) - arel - poltergeist (1.10.0) + pg (0.20.0) + pg_search (2.0.1) + activerecord (>= 4.2) + activesupport (>= 4.2) + arel (>= 6) + poltergeist (1.14.0) capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) powerpack (0.1.1) + public_suffix (2.0.5) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) rack (1.6.5) @@ -292,40 +301,40 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) - rails (4.2.7.1) - actionmailer (= 4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) - activemodel (= 4.2.7.1) - activerecord (= 4.2.7.1) - activesupport (= 4.2.7.1) + rails (4.2.8) + actionmailer (= 4.2.8) + actionpack (= 4.2.8) + actionview (= 4.2.8) + activejob (= 4.2.8) + activemodel (= 4.2.8) + activerecord (= 4.2.8) + activesupport (= 4.2.8) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.7.1) + railties (= 4.2.8) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.7) + rails-dom-testing (1.0.8) activesupport (>= 4.2.0.beta, < 5.0) - nokogiri (~> 1.6.0) + nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (4.2.7.1) - actionpack (= 4.2.7.1) - activesupport (= 4.2.7.1) + railties (4.2.8) + actionpack (= 4.2.8) + activesupport (= 4.2.8) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.1.0) + rainbow (2.2.1) raindrops (0.17.0) rake (12.0.0) - redcarpet (3.3.4) + redcarpet (3.4.0) referer-parser (0.3.0) - request_store (1.3.1) + request_store (1.3.2) responders (2.3.0) railties (>= 4.2.0, < 5.1) rinku (2.0.2) - rollbar (2.14.0) + rollbar (2.14.1) multi_json rspec-core (3.5.4) rspec-support (~> 3.5.0) @@ -344,8 +353,8 @@ GEM rspec-mocks (~> 3.5.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) - rubocop (0.45.0) - parser (>= 2.3.1.1, < 3.0) + rubocop (0.47.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) @@ -355,9 +364,9 @@ GEM capistrano (~> 3.0) sshkit (>= 1.2) safe_yaml (1.0.4) - safely_block (0.1.1) + safely_block (0.2.0) errbase - sass (3.4.22) + sass (3.4.23) sass-rails (5.0.6) railties (>= 4.0.0, < 6) sass (~> 3.1) @@ -377,12 +386,12 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.0) - sitemap_generator (5.2.0) + sitemap_generator (5.3.1) builder (~> 3.0) - social-share-button (0.3.1) + social-share-button (0.10.0) coffee-rails - sass-rails - spring (1.7.2) + spring (2.0.1) + activesupport (>= 4.2) spring-commands-rspec (1.0.4) spring (>= 0.9.1) sprockets (3.7.1) @@ -396,7 +405,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sshkit (1.11.4) + sshkit (1.12.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) term-ansicolor (1.4.0) @@ -405,10 +414,10 @@ GEM unicode-display_width (~> 1.1.1) thor (0.19.4) thread (0.2.2) - thread_safe (0.3.5) - tilt (2.0.5) + thread_safe (0.3.6) + tilt (2.0.7) timecop (0.8.1) - tins (1.13.0) + tins (1.13.2) tolk (2.0.0) rails (>= 4.0) safe_yaml (>= 0.8.6) @@ -421,9 +430,9 @@ GEM tilt (>= 1.4, < 3) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (3.0.4) + uglifier (3.1.9) execjs (>= 0.3.0, < 3) - unicode-display_width (1.1.1) + unicode-display_width (1.1.3) unicorn (5.2.0) kgio (~> 2.6) raindrops (~> 0.7) @@ -439,7 +448,7 @@ GEM activemodel (>= 4.2) debug_inspector railties (>= 4.2) - websocket-driver (0.6.4) + websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) whenever (0.9.7) @@ -453,20 +462,20 @@ PLATFORMS DEPENDENCIES acts-as-taggable-on acts_as_votable - ahoy_matey (~> 1.5.3) + ahoy_matey (~> 1.5.5) ancestry (~> 2.2.2) browser - bullet + bullet (~> 5.5.1) byebug - cancancan - capistrano (= 3.5.0) + cancancan (~> 1.16.0) + capistrano (~> 3.8.0) capistrano-bundler (~> 1.2) - capistrano-rails (= 1.1.8) - capistrano3-delayed-job (~> 1.0) - capybara + capistrano-rails (~> 1.2.3) + capistrano3-delayed-job (~> 1.7.3) + capybara (~> 2.13.0) ckeditor (~> 4.2.2) coffee-rails (~> 4.2.1) - coveralls + coveralls (~> 0.8.19) daemons dalli database_cleaner @@ -475,50 +484,53 @@ DEPENDENCIES devise-async devise_security_extension email_spec - factory_girl_rails - faker + factory_girl_rails (~> 4.8.0) + faker (~> 1.7.3) foundation-rails (~> 6.2.4.0) foundation_rails_helper (~> 2.0.0) fuubar - groupdate (~> 3.1.0) - i18n-tasks + groupdate (~> 3.2.0) + i18n-tasks (~> 0.9.12) initialjs-rails (= 0.2.0.4) invisible_captcha (~> 0.9.2) - jquery-rails (~> 4.2.2) + jquery-rails (~> 4.3.1) jquery-ui-rails - kaminari + kaminari (~> 1.0.1) knapsack launchy - letter_opener_web (~> 1.3.0) - newrelic_rpm (~> 3.17.2.327) + letter_opener_web (~> 1.3.1) + newrelic_rpm (~> 4.0.0.332) omniauth - omniauth-facebook (~> 3.0.0) + omniauth-facebook (~> 4.0.0) omniauth-google-oauth2 (~> 0.4.0) omniauth-twitter - paranoia (~> 2.2.0) - pg (~> 0.19.0) + paranoia (~> 2.2.1) + pg (~> 0.20.0) pg_search - poltergeist + poltergeist (~> 1.14.0) quiet_assets - rails (= 4.2.7.1) - redcarpet + rails (= 4.2.8) + redcarpet (~> 3.4.0) responders (~> 2.3.0) rinku (~> 2.0.2) - rollbar (~> 2.14.0) + rollbar (~> 2.14.1) rspec-rails (~> 3.5) - rubocop (~> 0.45.0) + rubocop (~> 0.47.1) rvm1-capistrano3 sass-rails (~> 5.0, >= 5.0.4) savon - sitemap_generator - social-share-button + sitemap_generator (~> 5.3.1) + social-share-button (~> 0.10) spring spring-commands-rspec sprockets (~> 3.7.1) tolk (~> 2.0.0) turbolinks turnout (~> 2.4.0) - uglifier (>= 3.0.4) + uglifier (~> 3.1.9) unicorn (~> 5.2.0) web-console (= 3.3.0) whenever + +BUNDLED WITH + 1.13.7 diff --git a/README.md b/README.md index c62fcfeec..20ed21003 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,19 @@ -![Logo of Consul] -(https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png) +![Logo of Consul](https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png) # Consul Citizen Participation and Open Government Application -[![Join the chat at https://gitter.im/consul/consul](https://badges.gitter.im/consul/consul.svg)](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/consul/consul.svg?branch=master)](https://travis-ci.org/consul/consul) [![Code Climate](https://codeclimate.com/github/consul/consul/badges/gpa.svg)](https://codeclimate.com/github/consul/consul) [![Dependency Status](https://gemnasium.com/consul/consul.svg)](https://gemnasium.com/consul/consul) [![Coverage Status](https://coveralls.io/repos/github/consul/consul/badge.svg?branch=master)](https://coveralls.io/github/consul/consul?branch=master) +[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](http://www.gnu.org/licenses/agpl-3.0) + +[![Accessibility conformance](https://img.shields.io/badge/accessibility-WAI:AA-green.svg)](https://www.w3.org/WAI/eval/Overview) +[![A11y issues checked with Rocket Validator](https://rocketvalidator.com/badges/checked_with_rocket_validator.svg?url=https://rocketvalidator.com)](https://rocketvalidator.com/opensource) + +[![Join the chat at https://gitter.im/consul/consul](https://badges.gitter.im/consul/consul.svg)](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website diff --git a/README_ES.md b/README_ES.md index 1b197e983..2c1e362c3 100644 --- a/README_ES.md +++ b/README_ES.md @@ -1,15 +1,20 @@ -![Logotipo de Consul] -(https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png) +![Logotipo de Consul](https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png) # Consul Aplicación de Participación Ciudadana y Gobierno Abierto -[![Join the chat at https://gitter.im/consul/consul](https://badges.gitter.im/consul/consul.svg)](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/consul/consul.svg?branch=master)](https://travis-ci.org/consul/consul) [![Code Climate](https://codeclimate.com/github/consul/consul/badges/gpa.svg)](https://codeclimate.com/github/consul/consul) [![Dependency Status](https://gemnasium.com/consul/consul.svg)](https://gemnasium.com/consul/consul) [![Coverage Status](https://coveralls.io/repos/github/consul/consul/badge.svg?branch=master)](https://coveralls.io/github/consul/consul?branch=master) +[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](http://www.gnu.org/licenses/agpl-3.0) + +[![Accessibility conformance](https://img.shields.io/badge/accessibility-WAI:AA-green.svg)](https://www.w3.org/WAI/eval/Overview) +[![A11y issues checked with Rocket Validator](https://rocketvalidator.com/badges/checked_with_rocket_validator.svg?url=https://rocketvalidator.com)](https://rocketvalidator.com/opensource) + +[![Join the chat at https://gitter.im/consul/consul](https://badges.gitter.im/consul/consul.svg)](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid. diff --git a/app/assets/fonts/icons.eot b/app/assets/fonts/icons.eot index c3c5d6289..60cfbaddb 100644 Binary files a/app/assets/fonts/icons.eot and b/app/assets/fonts/icons.eot differ diff --git a/app/assets/fonts/icons.svg b/app/assets/fonts/icons.svg index a548d9575..f45adea5a 100644 --- a/app/assets/fonts/icons.svg +++ b/app/assets/fonts/icons.svg @@ -56,6 +56,9 @@ - + + + + diff --git a/app/assets/fonts/icons.ttf b/app/assets/fonts/icons.ttf index 6f938f863..8f791759e 100644 Binary files a/app/assets/fonts/icons.ttf and b/app/assets/fonts/icons.ttf differ diff --git a/app/assets/fonts/icons.woff b/app/assets/fonts/icons.woff index f3c31e804..0eef00837 100644 Binary files a/app/assets/fonts/icons.woff and b/app/assets/fonts/icons.woff differ diff --git a/app/assets/images/more_info/budgets_en.png b/app/assets/images/more_info/budgets_en.png new file mode 100644 index 000000000..1c1002145 Binary files /dev/null and b/app/assets/images/more_info/budgets_en.png differ diff --git a/app/assets/images/more_info/budgets_es.png b/app/assets/images/more_info/budgets_es.png new file mode 100644 index 000000000..89d93947b Binary files /dev/null and b/app/assets/images/more_info/budgets_es.png differ diff --git a/app/assets/images/more_info/budgets_fr.png b/app/assets/images/more_info/budgets_fr.png new file mode 100644 index 000000000..1c1002145 Binary files /dev/null and b/app/assets/images/more_info/budgets_fr.png differ diff --git a/app/assets/images/more_info/budgets_pt-BR.png b/app/assets/images/more_info/budgets_pt-BR.png new file mode 100644 index 000000000..1c1002145 Binary files /dev/null and b/app/assets/images/more_info/budgets_pt-BR.png differ diff --git a/app/assets/images/more_info/debates.png b/app/assets/images/more_info/debates.png new file mode 100644 index 000000000..30b195668 Binary files /dev/null and b/app/assets/images/more_info/debates.png differ diff --git a/app/assets/images/more_info/proposals_en.png b/app/assets/images/more_info/proposals_en.png new file mode 100644 index 000000000..60357f222 Binary files /dev/null and b/app/assets/images/more_info/proposals_en.png differ diff --git a/app/assets/images/more_info/proposals_es.png b/app/assets/images/more_info/proposals_es.png new file mode 100644 index 000000000..3466949bb Binary files /dev/null and b/app/assets/images/more_info/proposals_es.png differ diff --git a/app/assets/images/more_info/proposals_fr.png b/app/assets/images/more_info/proposals_fr.png new file mode 100644 index 000000000..60357f222 Binary files /dev/null and b/app/assets/images/more_info/proposals_fr.png differ diff --git a/app/assets/images/more_info/proposals_pt-BR.png b/app/assets/images/more_info/proposals_pt-BR.png new file mode 100644 index 000000000..60357f222 Binary files /dev/null and b/app/assets/images/more_info/proposals_pt-BR.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 8b2e2674b..928f06edd 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,8 +12,8 @@ // //= require jquery //= require jquery_ujs -//= require jquery-ui/datepicker -//= require jquery-ui/datepicker-es +//= require jquery-ui/widgets/datepicker +//= require jquery-ui/i18n/datepicker-es //= require foundation //= require turbolinks //= require ckeditor/loader diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 36e055a4e..0720c103f 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -6,6 +6,7 @@ @import "admin"; @import "layout"; @import "participation"; +@import "pages"; @import "custom"; @import "c3"; @import "annotator.min"; diff --git a/app/assets/stylesheets/icons.scss b/app/assets/stylesheets/icons.scss index 33673486d..afbcc8bdd 100644 --- a/app/assets/stylesheets/icons.scss +++ b/app/assets/stylesheets/icons.scss @@ -190,3 +190,6 @@ .icon-checkmark-circle:before { content: "\59"; } +.icon-telegram:before { + content: "\31"; +} diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 10401c131..94d403528 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -70,6 +70,11 @@ a { } } +.button.hollow { + border: 1px solid $link; + color: $link; +} + .postfix.button { padding: 0; } @@ -1128,11 +1133,12 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar { // -------------------- [class^="level-"] { - color: white; + color: black; } .is-author { - background: #008CCF; + background: #00A5F1; + color: black; } .is-association { @@ -1190,7 +1196,11 @@ table { .button.button-twitter, .button.button-facebook, -.button.button-google { +.button.button-google, +.button.button-telegram { + background: white; + color: $text; + font-weight: bold; height: $line-height*2; line-height: $line-height*2; padding: 0; @@ -1198,9 +1208,11 @@ table { } .button.button-twitter { - background: #45B0E3; + background: #ECF7FC; + border-left: 3px solid #45B0E3; &:before { + color: #45B0E3; content: "f"; font-family: "icons" !important; font-size: rem-calc(24); @@ -1238,9 +1250,11 @@ table { } .button.button-facebook { - background: #3B5998; + background: #EBEEF4; + border-left: 3px solid #3B5998; &:before { + color: #3B5998; content: "A"; font-family: "icons" !important; font-size: rem-calc(24); @@ -1278,9 +1292,11 @@ table { } .button.button-google { - background: #DE4C34; + background: #FCEDEA; + border-left: 3px solid #DE4C34; &:before { + color: #DE4C34; content: "B"; font-family: "icons" !important; font-size: rem-calc(24); @@ -1317,6 +1333,48 @@ table { } } +.button.button-telegram { + background: #ECF7FC; + border-left: 3px solid #0088cc; + + &:before { + color: #0088cc; + content: "1"; + font-family: "icons" !important; + font-size: rem-calc(24); + left: 0; + line-height: $line-height*2; + padding: 0 rem-calc(20); + position: absolute; + top: 0; + } +} + +.ssb-telegram { + background: #0088cc; + background-image: none !important; + color: white; + height: $line-height*2 !important; + position: relative; + width: $line-height*2 !important; + + &:before { + content: "1"; + font-family: "icons" !important; + font-size: rem-calc(24); + left: 50%; + line-height: $line-height*2; + margin-left: rem-calc(-11); + position: absolute; + top: 0; + } + + &:hover, &:focus { + background: white; + color: #40A2D1; + } +} + .social { a { @@ -1408,6 +1466,30 @@ table { color: #CE3E26; } } + + .ssb-telegram { + background: #0088cc; + color: white; + height: $line-height; + position: relative; + width: $line-height*2; + + &:before { + content: "A"; + font-family: "icons" !important; + font-size: rem-calc(24); + left: 50%; + line-height: $line-height*2; + margin-left: rem-calc(-11); + position: absolute; + top: 0; + } + + &:hover, &:focus { + background: white; + color: #40A2D1; + } + } } // 13. Pages diff --git a/app/assets/stylesheets/pages.scss b/app/assets/stylesheets/pages.scss new file mode 100644 index 000000000..f8bf6c7cd --- /dev/null +++ b/app/assets/stylesheets/pages.scss @@ -0,0 +1,111 @@ +// Table of Contents +// +// 01. Header +// 02. Navigation +// 03. Content +// 04. Sidebar +// + +// 01. Header +// ---------------------- + +.jumbo { + margin-bottom: $line-height; + margin-top: rem-calc(-24); + padding-bottom: $line-height; + padding-top: $line-height; + + &.light { + background: #ECF0F1; + } +} + +.lead { + font-size: rem-calc(24); +} + +// 03. Navigation +// ---------------------- + +.menu-pages { + list-style-type: none; + margin: 0; + + li { + display: block; + + @include breakpoint(medium) { + display: inline-block; + margin-right: $line-height/2; + } + } +} + +// 03. Content +// ---------------------- + +.more-info-content { + + h3 { + color: $brand; + } + + .additional-info { + margin-bottom: $line-height; + } + + a:not(.button) { + text-decoration: underline; + } + + figure { + margin: 0; + text-align: center; + + figcaption { + font-size: $small-font-size; + font-style: italic; + } + } + + ul.features { + list-style-type: circle; + margin-left: $line-height; + + @include breakpoint(medium) { + margin: $line-height 0 $line-height $line-height*2.5; + } + + li { + margin-bottom: $line-height + } + } + + .section-content { + border-top: 1px solid $medium-gray; + padding-bottom: $line-height*2; + padding-top: $line-height*2; + + &:first-child { + border-top: 0; + padding-top: 0; + } + } +} + +// 04. Sidebar +// ---------------------- + +.more-info-sidebar { + + .sidebar-card { + border: 1px solid $border; + margin-bottom: $line-height; + padding: $line-height/2; + + &.light { + background: #ECF0F1; + border: 0; + } + } +} diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 66b4aca3d..ad413925b 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -457,7 +457,7 @@ } .bullet { - color: $border; + color: $text; } .investment-project-show p, .budget-investment-show p { @@ -976,6 +976,10 @@ &.social-share-button-google_plus:hover { color: #CE3E26; } + + &.social-share-button-telegram:hover { + color: #CE3E26; + } } } diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 0a5e78eef..7f9c6e7ee 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -55,7 +55,7 @@ module Budgets end def destroy - investment.destroy + @investment.destroy redirect_to user_path(current_user, filter: 'budget_investments'), notice: t('flash.actions.destroy.budget_investment') end diff --git a/app/controllers/concerns/commentable_actions.rb b/app/controllers/concerns/commentable_actions.rb index ef5e60dcb..ee69ac809 100644 --- a/app/controllers/concerns/commentable_actions.rb +++ b/app/controllers/concerns/commentable_actions.rb @@ -129,16 +129,16 @@ module CommentableActions when '4' 1.year.ago else - Date.parse(params[:advanced_search][:date_min]) rescue nil + Date.parse(params[:advanced_search][:date_min]) rescue 100.years.ago end end def search_finish_date - params[:advanced_search][:date_max].try(:to_date) || Date.today + (params[:advanced_search][:date_max].to_date rescue Date.today) || Date.today end def search_date_range - search_start_date.beginning_of_day..search_finish_date.end_of_day + [100.years.ago, search_start_date].max.beginning_of_day..[search_finish_date, Date.today].min.end_of_day end def set_search_order diff --git a/app/controllers/management/budgets_controller.rb b/app/controllers/management/budgets_controller.rb index c5cfdee76..dd7259c99 100644 --- a/app/controllers/management/budgets_controller.rb +++ b/app/controllers/management/budgets_controller.rb @@ -7,6 +7,11 @@ class Management::BudgetsController < Management::BaseController def create_investments @budgets = Budget.accepting.order(created_at: :desc).page(params[:page]) + + if current_manager_administrator? + @budgets += Budget.reviewing.order(created_at: :desc) + + Budget.selecting.order(created_at: :desc) + end end def support_investments @@ -23,4 +28,8 @@ class Management::BudgetsController < Management::BaseController check_verified_user t("management.budget_investments.alert.unverified_user") end + def current_manager_administrator? + session[:manager]["login"].match("admin") + end + end diff --git a/app/controllers/management/users_controller.rb b/app/controllers/management/users_controller.rb index 53004a838..8d3d148fa 100644 --- a/app/controllers/management/users_controller.rb +++ b/app/controllers/management/users_controller.rb @@ -32,7 +32,7 @@ class Management::UsersController < Management::BaseController private def user_params - params.require(:user).permit(:document_type, :document_number, :username, :email) + params.require(:user).permit(:document_type, :document_number, :username, :email, :date_of_birth) end def destroy_session diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 6b37d4e4e..3a07f0393 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -38,4 +38,8 @@ module BudgetsHelper def current_ballot Budget::Ballot.where(user: current_user, budget: @budget).first end + + def investment_tags_select_options + Budget::Investment.tags_on(:valuation).order(:name).select(:name).distinct + end end diff --git a/app/helpers/embed_videos_helper.rb b/app/helpers/embed_videos_helper.rb index 8633549f4..22b1d878f 100644 --- a/app/helpers/embed_videos_helper.rb +++ b/app/helpers/embed_videos_helper.rb @@ -2,6 +2,7 @@ module EmbedVideosHelper def embedded_video_code link = @proposal.video_url + title = t('proposals.show.embed_video_title', proposal: @proposal.title) if link.match(/vimeo.*/) server = "Vimeo" elsif link.match(/youtu*.*/) @@ -21,7 +22,7 @@ module EmbedVideosHelper end if match and match[2] - '' + '' else '' end diff --git a/app/helpers/signature_sheets_helper.rb b/app/helpers/signature_sheets_helper.rb index acd75a5ab..8e75dccfd 100644 --- a/app/helpers/signature_sheets_helper.rb +++ b/app/helpers/signature_sheets_helper.rb @@ -2,7 +2,7 @@ module SignatureSheetsHelper def signable_options [[t("activerecord.models.proposal", count: 1), Proposal], - [t("activerecord.models.spending_proposal", count: 1), SpendingProposal]] + [t("activerecord.models.budget/investment", count: 1), Budget::Investment]] end end \ No newline at end of file diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index b5d142c94..6a8ef594c 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -46,6 +46,7 @@ module Abilities can :create, SpendingProposal can :create, Budget::Investment, budget: { phase: "accepting" } + can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id can :vote, Budget::Investment, budget: { phase: "selecting" } can [:show, :create], Budget::Ballot, budget: { phase: "balloting" } can [:create, :destroy], Budget::Ballot::Line, budget: { phase: "balloting" } diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 100433707..4bfd038c3 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -25,6 +25,7 @@ class Budget validates :description, presence: true validates :heading_id, presence: true validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required? + validates_presence_of :price, if: :price_required? validates :title, length: { in: 4..Budget::Investment.title_max_length } validates :description, length: { maximum: Budget::Investment.description_max_length } @@ -136,6 +137,10 @@ class Budget unfeasible? && valuation_finished? end + def price_required? + feasible? && valuation_finished? + end + def unfeasible_email_pending? unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished? end @@ -225,7 +230,7 @@ class Budget def should_show_aside? (budget.selecting? && !unfeasible?) || (budget.balloting? && feasible?) || - (budget.valuating? && feasible?) + (budget.valuating? && !unfeasible?) end def should_show_votes? @@ -259,7 +264,7 @@ class Budget private def set_denormalized_ids - self.group_id ||= self.heading.try(:group_id) + self.group_id = self.heading.try(:group_id) if self.heading_id_changed? self.budget_id ||= self.heading.try(:group).try(:budget_id) end end diff --git a/app/models/signature.rb b/app/models/signature.rb index e75039355..543965aed 100644 --- a/app/models/signature.rb +++ b/app/models/signature.rb @@ -12,35 +12,30 @@ class Signature < ActiveRecord::Base before_validation :clean_document_number - def verified? - user_exists? || in_census? - end - def verify - if verified? - assign_vote - mark_as_verified - end - end - - def assign_vote if user_exists? assign_vote_to_user - else + mark_as_verified + elsif in_census? create_user assign_vote_to_user + mark_as_verified end end def assign_vote_to_user set_user - signable.register_vote(user, "yes") + if signable.is_a? Budget::Investment + signable.vote_by(voter: user, vote: 'yes') if [nil, :no_selecting_allowed].include?(signable.reason_for_not_being_selectable_by(user)) + else + signable.register_vote(user, "yes") + end assign_signature_to_vote end def assign_signature_to_vote vote = Vote.where(votable: signable, voter: user).first - vote.update(signature: self) + vote.update(signature: self) if vote end def user_exists? @@ -55,7 +50,10 @@ class Signature < ActiveRecord::Base erased_at: Time.current, password: random_password, terms_of_service: '1', - email: nil + email: nil, + date_of_birth: @census_api_response.date_of_birth, + gender: @census_api_response.gender, + geozone: Geozone.where(census_code: @census_api_response.district_code).first } User.create!(user_params) end @@ -70,10 +68,17 @@ class Signature < ActiveRecord::Base end def in_census? - response = document_types.detect do |document_type| - CensusApi.new.call(document_type, document_number).valid? + document_types.detect do |document_type| + response = CensusApi.new.call(document_type, document_number) + if response.valid? + @census_api_response = response + true + else + false + end end - response.present? + + @census_api_response.present? end def set_user diff --git a/app/models/signature_sheet.rb b/app/models/signature_sheet.rb index 9720c891f..1434143ac 100644 --- a/app/models/signature_sheet.rb +++ b/app/models/signature_sheet.rb @@ -2,7 +2,7 @@ class SignatureSheet < ActiveRecord::Base belongs_to :signable, polymorphic: true belongs_to :author, class_name: 'User', foreign_key: 'author_id' - VALID_SIGNABLES = %w( Proposal SpendingProposal ) + VALID_SIGNABLES = %w( Proposal Budget::Investment SpendingProposal ) has_many :signatures diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb index 126a933b7..beb5eb856 100644 --- a/app/views/admin/budget_investments/index.html.erb +++ b/app/views/admin/budget_investments/index.html.erb @@ -28,7 +28,7 @@
<%= select_tag :tag_name, - options_for_select(spending_proposal_tags_select_options, params[:tag_name]), + options_for_select(investment_tags_select_options, params[:tag_name]), { prompt: t("admin.budget_investments.index.tags_filter_all"), label: false, class: "js-submit-on-change" } %> diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb index 422834f61..e90bd4905 100644 --- a/app/views/admin/budgets/_group.html.erb +++ b/app/views/admin/budgets/_group.html.erb @@ -7,23 +7,24 @@ - <% if headings.blank? %> - - - -
- <%= t("admin.budgets.form.no_heading") %> -
- - - <% else %> - - <%= t("admin.budgets.form.table_heading") %> - <%= t("admin.budgets.form.table_amount") %> - - - - <% end %> + <% if headings.blank? %> + + + + +
+ <%= t("admin.budgets.form.no_heading") %> +
+ + + <% else %> + + <%= t("admin.budgets.form.table_heading") %> + <%= t("admin.budgets.form.table_amount") %> + + + + <% end %> @@ -52,16 +53,15 @@ <% headings.each do |heading| %> - - - <%= heading.name %> - - - <%= heading.price %> - - + + + <%= heading.name %> + + + <%= heading.price %> + + <% end %> - - -
+ + diff --git a/app/views/budgets/index.html.erb b/app/views/budgets/index.html.erb index 73fc3a697..f3e386d27 100644 --- a/app/views/budgets/index.html.erb +++ b/app/views/budgets/index.html.erb @@ -10,8 +10,10 @@
- - + + + + <% @budgets.each do |budget| %> diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index 17abf4faf..d97a1fbfb 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -103,8 +103,9 @@ diff --git a/app/views/debates/new.html.erb b/app/views/debates/new.html.erb index cd4a92cc6..ccd11bec2 100644 --- a/app/views/debates/new.html.erb +++ b/app/views/debates/new.html.erb @@ -7,7 +7,7 @@
<%= t("debates.new.info", info_link: link_to(t("debates.new.info_link"), new_proposal_path )).html_safe %> - <%= link_to "/more_information", title: t('shared.target_blank_html'), target: "_blank" do %> + <%= link_to more_info_path, title: t('shared.target_blank_html'), target: "_blank" do %> <%= t("debates.new.more_info") %> <% end %>
diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb index 363a3bab3..64eafc0ae 100644 --- a/app/views/debates/show.html.erb +++ b/app/views/debates/show.html.erb @@ -53,8 +53,9 @@ diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb index fe2cf0dc5..51f6cf1eb 100644 --- a/app/views/devise/confirmations/new.html.erb +++ b/app/views/devise/confirmations/new.html.erb @@ -19,6 +19,7 @@ <%= f.submit(t("devise_views.confirmations.new.submit"), class: "button expanded") %> + <% end %> <%= render "devise/shared/links" %> diff --git a/app/views/devise/menu/_login_items.html.erb b/app/views/devise/menu/_login_items.html.erb index 0ab28e2ee..b7db4a22c 100644 --- a/app/views/devise/menu/_login_items.html.erb +++ b/app/views/devise/menu/_login_items.html.erb @@ -1,6 +1,6 @@ <% if user_signed_in? %>
  • - <%= link_to notifications_path, class: "notifications", accesskey: "n" do %> + <%= link_to notifications_path, class: "notifications" do %> <%= t("layouts.header.notifications") %> <% if current_user.notifications_count > 0 %> @@ -12,19 +12,19 @@ <% end %>
  • - <%= link_to(t("layouts.header.my_activity_link"), user_path(current_user), accesskey: "a") %> + <%= link_to t("layouts.header.my_activity_link"), user_path(current_user) %>
  • - <%= link_to(t("layouts.header.my_account_link"), account_path, accesskey: "m") %> + <%= link_to t("layouts.header.my_account_link"), account_path %>
  • - <%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %> + <%= link_to t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete %>
  • <% else %>
  • - <%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %> + <%= link_to t("devise_views.menu.login_items.login"), new_user_session_path %>
  • - <%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button") %> + <%= link_to t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button" %>
  • <% end %> diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb index 72dd70fb9..b06c9ff25 100644 --- a/app/views/devise/passwords/new.html.erb +++ b/app/views/devise/passwords/new.html.erb @@ -11,6 +11,7 @@ <%= f.submit t("devise_views.passwords.new.send_submit"), class: "button expanded" %> + <% end %> <%= render "devise/shared/links" %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index ad375e772..910135853 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -11,18 +11,18 @@ <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
    - <%= f.email_field :email, autofocus: true, placeholder: t("devise_views.sessions.new.email_label"), tabindex: "1" %> + <%= f.email_field :email, autofocus: true, placeholder: t("devise_views.sessions.new.email_label") %>
    - <%= link_to t("devise_views.shared.links.new_password"), new_password_path(resource_name), class: "float-right", tabindex: "3" %> - <%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.sessions.new.password_label"), tabindex: "2" %> + <%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.sessions.new.password_label") %> + <%= link_to t("devise_views.shared.links.new_password"), new_password_path(resource_name), class: "float-right" %>
    <% if devise_mapping.rememberable? -%>
    <%= f.label :remember_me do %> - <%= f.check_box :remember_me, title: t('devise_views.sessions.new.remember_me'), label: false, tabindex: "4" %> + <%= f.check_box :remember_me, title: t('devise_views.sessions.new.remember_me'), label: false %> <%= t("devise_views.sessions.new.remember_me") %> <% end %>
    @@ -35,5 +35,3 @@ <% end %> <%= render "devise/shared/links" %> - - diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 4f8545fb5..4b5e90523 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -43,7 +43,6 @@
    <%= t("layouts.footer.copyright", year: Time.current.year) %> |
      -
    • <%= link_to t("layouts.footer.more_info"), page_path('more_information') %> |
    • <%= link_to t("layouts.footer.privacy"), page_path('privacy') %> |
    • <%= link_to t("layouts.footer.conditions"), page_path('conditions') %> |
    • <%= link_to t("layouts.footer.accessibility"), page_path('accessibility') %>
    • @@ -85,6 +84,14 @@ <% end %> <% end %> + <% if setting['telegram_handle'] %> +
    • + <%= link_to "https://www.telegram.me/#{setting['telegram_handle']}", target: "_blank", title: t("social.telegram") + t('shared.target_blank_html') do %> + <%= t("social.telegram") %> + + <% end %> +
    • + <% end %>
    diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 223f173b2..9a33662c6 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -21,7 +21,7 @@
    - <%= link_to root_path, class: "hide-for-small-only", accesskey: "/" do %> + <%= link_to root_path, class: "hide-for-small-only", accesskey: "0" do %> <%= image_tag('logo_header.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> <%= setting['org_name'] %> <% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ce84c44af..4f92768dc 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -20,9 +20,11 @@ type: "image/png" %> <%= content_for :social_media_meta_tags %> - <%= setting['per_page_code'].try(:html_safe) %> + <%= setting['per_page_code_head'].try(:html_safe) %> + <%= setting['per_page_code_body'].try(:html_safe) %> +

    <%= setting['org_name'] %>

    diff --git a/app/views/management/users/new.html.erb b/app/views/management/users/new.html.erb index 6602e4978..d52597590 100644 --- a/app/views/management/users/new.html.erb +++ b/app/views/management/users/new.html.erb @@ -4,7 +4,7 @@ message: t("management.document_verifications.in_census_has_following_permissions"), permissions: [:debates, :create_proposals, :support_proposals, :vote_proposals] %> -
    +
    <%= Budget.human_attribute_name(:name) %><%= Budget.human_attribute_name(:phase) %>
    <%= Budget.human_attribute_name(:name) %><%= Budget.human_attribute_name(:phase) %>
    + - - + + - + - + - + - + + + + + - - - - - - - - - - - - - - - -
    Atajos de teclado para el menú de navegación
    TeclaPáginaTeclaPágina
    /0 Inicio
    D1 Debates
    P2 Propuestas
    S3Votaciones
    4 Presupuestos participativos
    IMás información
    NNotificaciones
    AMi actividad
    MMi cuenta
    @@ -66,10 +55,11 @@
    + - - + + @@ -104,8 +94,8 @@
    Combinación de teclas dependiendo del sistema operativo y navegador
    NavegadorCombinación de teclasNavegadorCombinación de teclas
    - - + + diff --git a/app/views/pages/how_it_works.html.erb b/app/views/pages/how_it_works.html.erb deleted file mode 100644 index 67fb38371..000000000 --- a/app/views/pages/how_it_works.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -
    - - -
    -

    <%= t('pages.more_information.titles.how_it_works') %>

    - <%= markdown t('pages.more_information.how_it_works.text') %> -
    -
    diff --git a/app/views/pages/how_to_use.html.erb b/app/views/pages/how_to_use.html.erb deleted file mode 100644 index a594961a8..000000000 --- a/app/views/pages/how_to_use.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -
    -
    - <%= render "shared/back_link" %> - -

    <%= t('pages.more_information.titles.how_to_use') %>

    - - <%= markdown t('pages.more_information.how_to_use.text') %> -
    -
    diff --git a/app/views/pages/more_info/_budgets.html.erb b/app/views/pages/more_info/_budgets.html.erb new file mode 100644 index 000000000..b2f34d690 --- /dev/null +++ b/app/views/pages/more_info/_budgets.html.erb @@ -0,0 +1,26 @@ +
    +
    +

    + <%= t("pages.more_info.budgets.title") %> +

    +

    + <%= link_to t("pages.more_info.budgets.detail"), more_info_budgets_path, class: "small" %> +

    +

    <%= t("pages.more_info.budgets.description") %>

    +
      +
    • + <%= t("pages.more_info.budgets.feature_1", + link: link_to(t("pages.more_info.budgets.feature_1_link", org_name: setting['org_name']), + new_user_registration_path)).html_safe %> +
    • +
    • <%= t("pages.more_info.budgets.feature_2_html") %>
    • +
    • <%= t("pages.more_info.budgets.feature_3_html") %>
    • +
    • <%= t("pages.more_info.budgets.feature_4_html") %>
    • +
    + +
    + <%= image_tag "more_info/budgets_#{I18n.locale}.png", alt: t("pages.more_info.budgets.image_alt") %> +
    <%= t("pages.more_info.budgets.figcaption_html") %>
    +
    +
    +
    diff --git a/app/views/pages/more_info/_debates.html.erb b/app/views/pages/more_info/_debates.html.erb new file mode 100644 index 000000000..a8e76ba91 --- /dev/null +++ b/app/views/pages/more_info/_debates.html.erb @@ -0,0 +1,21 @@ +
    +
    +

    + <%= t("pages.more_info.debates.title") %> +

    +

    <%= t("pages.more_info.debates.description") %>

    +
      +
    • + <%= t("pages.more_info.debates.feature_1", + link: link_to(t("pages.more_info.debates.feature_1_link", org_name: setting['org_name']), + new_user_registration_path)).html_safe %> +
    • +
    • <%= t("pages.more_info.debates.feature_2_html") %>
    • +
    + +
    + <%= image_tag "more_info/debates.png", alt: t("pages.more_info.debates.image_alt") %> +
    <%= t("pages.more_info.debates.figcaption") %>
    +
    +
    +
    diff --git a/app/views/pages/more_info/_menu.html.erb b/app/views/pages/more_info/_menu.html.erb new file mode 100644 index 000000000..85097e6a8 --- /dev/null +++ b/app/views/pages/more_info/_menu.html.erb @@ -0,0 +1,22 @@ +
    +
    + +
    +
    diff --git a/app/views/pages/more_info/_other.html.erb b/app/views/pages/more_info/_other.html.erb new file mode 100644 index 000000000..d0718294c --- /dev/null +++ b/app/views/pages/more_info/_other.html.erb @@ -0,0 +1,7 @@ +

    Otra información de interés

    + +
      +
    • <%= link_to t("pages.more_info.other.how_to_use", org_name: setting['org_name']), faq_path %>
    • +
    • <%= link_to t("pages.more_info.other.facts"), participation_facts_path %>
    • +
    • <%= link_to t("pages.more_info.other.world"), participation_world_path %>
    • +
    diff --git a/app/views/pages/more_info/_proposals.html.erb b/app/views/pages/more_info/_proposals.html.erb new file mode 100644 index 000000000..b93acfa62 --- /dev/null +++ b/app/views/pages/more_info/_proposals.html.erb @@ -0,0 +1,25 @@ +
    +
    +

    + <%= t("pages.more_info.proposals.title") %> +

    +

    + <%= link_to t("pages.more_info.proposals.detail"), more_info_proposals_path, class: "small" %> +

    +

    <%= t("pages.more_info.proposals.description") %>

    +
      +
    • + <%= t("pages.more_info.proposals.feature_1", + link: link_to(t("pages.more_info.proposals.feature_1_link", org_name: setting['org_name']), + new_user_registration_path)).html_safe %> +
    • +
    • <%= t("pages.more_info.proposals.feature_2_html") %>
    • +
    • <%= t("pages.more_info.proposals.feature_3_html") %>
    • +
    + +
    + <%= image_tag "more_info/proposals_#{I18n.locale}.png", alt: t("pages.more_info.proposals.image_alt") %> +
    <%= t("pages.more_info.proposals.figcaption_html") %>
    +
    +
    +
    diff --git a/app/views/pages/more_info/_sidebar.html.erb b/app/views/pages/more_info/_sidebar.html.erb new file mode 100644 index 000000000..09131685b --- /dev/null +++ b/app/views/pages/more_info/_sidebar.html.erb @@ -0,0 +1,5 @@ + diff --git a/app/views/pages/spending_proposals_info.html.erb b/app/views/pages/more_info/budgets/index.html similarity index 100% rename from app/views/pages/spending_proposals_info.html.erb rename to app/views/pages/more_info/budgets/index.html diff --git a/app/views/pages/faq.html.erb b/app/views/pages/more_info/faq/index.html similarity index 100% rename from app/views/pages/faq.html.erb rename to app/views/pages/more_info/faq/index.html diff --git a/app/views/pages/more_info/how_to_use/index.html.erb b/app/views/pages/more_info/how_to_use/index.html.erb new file mode 100644 index 000000000..9c6ccfb00 --- /dev/null +++ b/app/views/pages/more_info/how_to_use/index.html.erb @@ -0,0 +1,9 @@ +
    +
    + <%= render "shared/back_link" %> + +

    <%= t('pages.more_info.titles.how_to_use') %>

    + + <%= markdown t('pages.more_info.how_to_use.text') %> +
    +
    diff --git a/app/views/pages/more_info/index.html.erb b/app/views/pages/more_info/index.html.erb new file mode 100644 index 000000000..4c40a9fee --- /dev/null +++ b/app/views/pages/more_info/index.html.erb @@ -0,0 +1,39 @@ +<% provide :title do %><%= t("pages.titles.more_info", org_name: setting['org_name']) %><% end %> + +
    +
    +
    +

    <%= t("pages.more_info.title", org_name: setting['org_name']) %>

    +

    <%= t("pages.more_info.subtitle") %>

    +

    <%= t("pages.more_info.guide", org_name: setting['org_name']) %>

    +
    +
    + + <%= render "pages/more_info/menu" %> +
    + +
    +
    +
    + <% if feature?(:debates) %> + <%= render "pages/more_info/debates" %> + <% end %> + + <%= render "pages/more_info/proposals" %> + + <% if feature?(:budgets) %> + <%= render "pages/more_info/budgets" %> + <% end %> +
    +
    + <%= render "pages/more_info/sidebar" %> +
    +
    + +
    +
    +
    + <%= render "pages/more_info/other" %> +
    +
    +
    diff --git a/app/views/pages/participation_facts.html.erb b/app/views/pages/more_info/participation/facts.html.erb similarity index 100% rename from app/views/pages/participation_facts.html.erb rename to app/views/pages/more_info/participation/facts.html.erb diff --git a/app/views/pages/participation_world.html.erb b/app/views/pages/more_info/participation/world.html.erb similarity index 100% rename from app/views/pages/participation_world.html.erb rename to app/views/pages/more_info/participation/world.html.erb diff --git a/app/views/pages/proposals_info.html.erb b/app/views/pages/more_info/proposals/index.html.erb similarity index 100% rename from app/views/pages/proposals_info.html.erb rename to app/views/pages/more_info/proposals/index.html.erb diff --git a/app/views/pages/more_information.html.erb b/app/views/pages/more_information.html.erb deleted file mode 100644 index 07105ef0f..000000000 --- a/app/views/pages/more_information.html.erb +++ /dev/null @@ -1,71 +0,0 @@ -<% provide :title do %><%= t('pages.titles.more_information') %><% end %> -
    -
    -

    <%= t('pages.titles.more_information') %>

    -
      -
    • - <%= link_to page_path('how_it_works') do %> - <%= t('pages.more_information.titles.how_it_works') %> -
      - <%= t('pages.more_information.description.how_it_works') %> - <% end %> -
    • -
    • - <%= link_to page_path('how_to_use') do %> - <%= t('pages.more_information.titles.how_to_use') %> -
      - <%= t('pages.more_information.description.how_to_use') %> - <% end %> -
    • -
    • - <%= link_to page_path('participation') do %> - <%= t('pages.more_information.titles.participation') %> -
      - <%= t('pages.more_information.description.participation') %> - <% end %> -
    • -
    • - <%= link_to page_path('proposals_info') do %> - <%= t('pages.more_information.titles.proposals_info') %> -
      - <%= t('pages.more_information.description.proposals_info') %> - <% end %> -
    • -
    • - <%= link_to page_path('spending_proposals_info') do %> - <%= t('pages.more_information.titles.spending_proposals_info') %> -
      - <%= t('pages.more_information.description.spending_proposals_info') %> - <% end %> -
    • -
    • - <%= link_to page_path('participation_world') do %> - <%= t('pages.more_information.titles.participation_world') %> -
      - <%= t('pages.more_information.description.participation_world') %> - <% end %> -
    • -
    • - <%= link_to page_path('participation_facts') do %> - <%= t('pages.more_information.titles.participation_facts') %> -
      - <%= t('pages.more_information.description.participation_facts') %> - <% end %> -
    • -
    • - <%= link_to page_path('faq') do %> - <%= t('pages.more_information.titles.faq') %> -
      - <%= t('pages.more_information.description.faq') %> - <% end %> -
    • -
    • - <%= link_to page_path('proposals_info', :anchor => "iii") do %> - <%= t('pages.more_information.titles.signature_sheet') %> -
      - <%= t('pages.more_information.description.signature_sheet') %> - <% end %> -
    • -
    -
    -
    diff --git a/app/views/pages/opendata.html.erb b/app/views/pages/opendata.html.erb deleted file mode 100644 index aeee6b465..000000000 --- a/app/views/pages/opendata.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -<% provide :title do %><%= t('pages.titles.opendata') %><% end %> - -
    -
    -
    -

    <%= t("pages.opendata.title") %>

    -

    <%= t("pages.opendata.slogan") %>

    -
    - -
    - <%= image_tag("icon_home.png", size: "330x240", alt:"") %> -
    -
    -
    diff --git a/app/views/pages/participation.html.erb b/app/views/pages/participation.html.erb deleted file mode 100644 index 9d92140fb..000000000 --- a/app/views/pages/participation.html.erb +++ /dev/null @@ -1,46 +0,0 @@ -
    - - -
    -

    Participación y Transparencia

    - -

    Página de información sobre Participación y Transparencia.

    - -

    I. Participación.

    - -
      -
    • I.1. Participación. Información sobre Participación
    • -
    • I.1. Participación. Información sobre Participación
    • -
    • I.1. Participación. Información sobre Participación
    • -
    - -

    II. Transparencia

    - -
      -
    • II.1. Transparencia Información sobre Transparencia
    • -
    • II.1. Transparencia Información sobre Transparencia
    • -
    • II.1. Transparencia Información sobre Transparencia
    • -
    -
    -
    diff --git a/app/views/proposals/_filter_subnav.html.erb b/app/views/proposals/_filter_subnav.html.erb index fe875c9a9..6347d56b0 100644 --- a/app/views/proposals/_filter_subnav.html.erb +++ b/app/views/proposals/_filter_subnav.html.erb @@ -1,6 +1,6 @@
    -
      +
      • <%= link_to "#tab-comments" do %>

        diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 2ba88f688..80b2d25a9 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -132,8 +132,9 @@ @@ -142,7 +143,7 @@

    <% end %> -
    +
    <%= render "proposals/filter_subnav" %> <%= render "proposals/notifications" %> diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 5e12264a2..13bbb9d01 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -11,7 +11,8 @@ <% end %> - <% if feature?(:spending_proposals) && (current_user.administrator? || current_user.valuator?) %> + <% if (feature?(:spending_proposals) || feature?(:budgets)) && + (current_user.administrator? || current_user.valuator?) %>
  • <%= link_to t("layouts.header.valuation"), valuation_root_path %>
  • diff --git a/app/views/shared/_advanced_search.html.erb b/app/views/shared/_advanced_search.html.erb index 7ce6108b4..558adc806 100644 --- a/app/views/shared/_advanced_search.html.erb +++ b/app/views/shared/_advanced_search.html.erb @@ -36,8 +36,6 @@ <%= text_field_tag 'advanced_search[date_min]', params[:advanced_search].try(:[], :date_min), - type: "date", - placeholder: t("shared.advanced_search.date_placeholder"), class: 'js-calendar' %>
    @@ -46,8 +44,6 @@ <%= text_field_tag 'advanced_search[date_max]', params[:advanced_search].try(:[], :date_max), - type: "date", - placeholder: t("shared.advanced_search.date_placeholder"), class: 'js-calendar' %>
    diff --git a/app/views/shared/_subnavigation.html.erb b/app/views/shared/_subnavigation.html.erb index 21ab08ca2..991d771ce 100644 --- a/app/views/shared/_subnavigation.html.erb +++ b/app/views/shared/_subnavigation.html.erb @@ -3,23 +3,23 @@ <% if feature?(:debates) %>
  • <%= layout_menu_link_to t("layouts.header.debates"), - debates_path, - controller_name == 'debates', - accesskey: "d" %> + debates_path, + controller_name == 'debates', + accesskey: "1" %>
  • <% end %>
  • <%= layout_menu_link_to t("layouts.header.proposals"), proposals_path, controller_name == 'proposals', - accesskey: "p" %> + accesskey: "2" %>
  • <% if feature?(:polls) %>
  • <%= layout_menu_link_to t("layouts.header.poll_questions"), polls_path, controller_name == "polls", - accesskey: "v" %> + accesskey: "3" %>
  • <% end %> <% if feature?(:spending_proposals) %> @@ -35,8 +35,14 @@ <%= layout_menu_link_to t("layouts.header.budgets"), budgets_path, controller_name == "budgets" || controller_name == "investments", - accesskey: "b" %> + accesskey: "4" %> <% end %> +
  • + <%= link_to t("layouts.header.more_info"), + more_info_path, + accesskey: "5", + class: ("active" if current_page?(more_info_path)) %> +
  • diff --git a/app/views/shared/_tags.html.erb b/app/views/shared/_tags.html.erb index 3cdb3c40e..ec2b7a1b1 100644 --- a/app/views/shared/_tags.html.erb +++ b/app/views/shared/_tags.html.erb @@ -5,8 +5,7 @@ <% taggable.tag_list_with_limit(limit).each do |tag| %>
  • <%= link_to sanitize(tag.name), - taggables_path(taggable.class.name.underscore, tag.name), - search: tag.name %>
  • + taggables_path(taggable.class.name.underscore, tag.name) %> <% end %> <% if taggable.tags_count_out_of_limit(limit) > 0 %> diff --git a/app/views/shared/_top_links.html.erb b/app/views/shared/_top_links.html.erb index b6b738aca..b97499232 100644 --- a/app/views/shared/_top_links.html.erb +++ b/app/views/shared/_top_links.html.erb @@ -1,10 +1,4 @@ + <% end %>
    NavegadorAcción a realizar NavegadorAcción a realizar
    <%= link_to budget_investment.title, budget_investment_path(budget_investment.budget, budget_investment) %> + <% if can? :destroy, budget_investment %> + <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), + method: :delete, class: "button hollow alert" %> + <% end %> +
    diff --git a/app/views/users/registrations/new.html.erb b/app/views/users/registrations/new.html.erb index 1c6f81455..3ae3156f7 100644 --- a/app/views/users/registrations/new.html.erb +++ b/app/views/users/registrations/new.html.erb @@ -19,7 +19,7 @@ <%= f.label :username %>

    <%= t("devise_views.users.registrations.new.username_note") %>

    - <%= f.text_field :username, maxlength: User.username_max_length, placeholder: t("devise_views.users.registrations.new.username_label"), label: false %> + <%= f.text_field :username, autofocus: true, maxlength: User.username_max_length, placeholder: t("devise_views.users.registrations.new.username_label"), label: false %> <%= f.invisible_captcha :family_name %> diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 978ff489c..32124a950 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -4,7 +4,7 @@

    <%= t("layouts.header.open_city_title") %>

    <%= t("layouts.header.open_city_slogan_html") %>  - <%= link_to t("layouts.header.more_information"), page_path('more_information') %> + <%= link_to t("layouts.header.more_info"), more_info_path %>

    <%= link_to t("layouts.header.see_all"), proposals_path, class: "button see-more expanded" %> diff --git a/config/deploy.rb b/config/deploy.rb index 52fa7a255..fa786ee85 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,5 +1,5 @@ # config valid only for current version of Capistrano -lock '3.5.0' +lock '3.8.0' def deploysecret(key) @deploy_secrets_yml ||= YAML.load_file('config/deploy-secrets.yml')[fetch(:stage).to_s] @@ -15,7 +15,6 @@ set :full_app_name, deploysecret(:full_app_name) set :server_name, deploysecret(:server_name) set :repo_url, 'https://github.com/consul/consul.git' -set :scm, :git set :revision, `git rev-parse --short #{fetch(:branch)}`.strip set :log_level, :info @@ -56,4 +55,4 @@ task :install_bundler_gem do on roles(:app) do execute "rvm use #{fetch(:rvm1_ruby_version)}; gem install bundler" end -end \ No newline at end of file +end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 17dcc43ec..aa9473201 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -22,6 +22,8 @@ data: ## Another gem (replace %#= with %=): # - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml" - config/locales/%{locale}.yml + - config/locales/activerecord.%{locale}.yml + - config/locales/activemodel.%{locale}.yml - config/locales/admin.%{locale}.yml - config/locales/moderation.%{locale}.yml - config/locales/valuation.%{locale}.yml diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb index 45c2b70e4..b1d87b01b 100644 --- a/config/initializers/kaminari_config.rb +++ b/config/initializers/kaminari_config.rb @@ -8,50 +8,3 @@ Kaminari.configure do |config| # config.page_method_name = :page # config.param_name = :page end - - -# Overrides for making Kaminari handle i18n pluralization correctly -# -# Remove everything below once https://github.com/amatsuda/kaminari/pull/694 is -# merged in Kaminari and we have updated -module Kaminari - - module ActionViewExtension - def page_entries_info(collection, options = {}) - entry_name = if options[:entry_name] - options[:entry_name].pluralize(collection.size) - else - collection.entry_name(:count => collection.size).downcase - end - - if collection.total_pages < 2 - t('helpers.page_entries_info.one_page.display_entries', entry_name: entry_name, count: collection.total_count) - else - first = collection.offset_value + 1 - last = collection.last_page? ? collection.total_count : collection.offset_value + collection.limit_value - t('helpers.page_entries_info.more_pages.display_entries', entry_name: entry_name, first: first, last: last, total: collection.total_count) - end.html_safe - end - end - - module ActiveRecordRelationMethods - def entry_name(options = {}) - model_name.human(options.reverse_merge(default: model_name.human.pluralize(options[:count]))) - end - end - - module MongoidCriteriaMethods - def entry_name(options = {}) - model_name.human(options.reverse_merge(default: model_name.human.pluralize(options[:count]))) - end - end - - class PaginatableArray < Array - ENTRY = 'entry'.freeze - - def entry_name(options = {}) - I18n.t('helpers.page_entries_info.entry', options.reverse_merge(default: ENTRY.pluralize(options[:count]))) - end - end - -end diff --git a/config/initializers/social_share_button.rb b/config/initializers/social_share_button.rb index d8b6e5254..6ee0fa0ed 100644 --- a/config/initializers/social_share_button.rb +++ b/config/initializers/social_share_button.rb @@ -1,3 +1,3 @@ SocialShareButton.configure do |config| - config.allow_sites = %w(twitter facebook google_plus) + config.allow_sites = %w(twitter facebook google_plus telegram) end diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index f55e82d1e..1451b2fe8 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -8,8 +8,8 @@ es: one: "Presupuesto participativo" other: "Presupuestos participativos" budget/investment: - one: "Propuesta de inversión" - other: "Propuestas de inversión" + one: "Proyecto de inversión" + other: "Proyectos de inversión" comment: one: "Comentario" other: "Comentarios" @@ -49,13 +49,13 @@ es: attributes: budget: name: "Nombre" - description_accepting: "Descripción durante la fase de aceptación" - description_reviewing: "Descripción durante la fase de revisión" - description_selecting: "Descripción durante la fase de selección" + description_accepting: "Descripción durante la fase de presentación de proyectos" + description_reviewing: "Descripción durante la fase de revisión interna" + description_selecting: "Descripción durante la fase de apoyos" description_valuating: "Descripción durante la fase de evaluación" description_balloting: "Descripción durante la fase de votación" description_reviewing_ballots: "Descripción durante la fase de revisión de votos" - description_finished: "Descripción cuando el presupuesto ha finalizado" + description_finished: "Descripción cuando el presupuesto ha finalizado / Resultados" phase: "Fase" currency_symbol: "Divisa" budget/investment: @@ -138,6 +138,10 @@ es: attributes: tag_list: less_than_or_equal_to: "los temas deben ser menor o igual que %{count}" + budget/investment: + attributes: + tag_list: + less_than_or_equal_to: "los temas deben ser menor o igual que %{count}" proposal_notification: attributes: minimum_interval: diff --git a/config/locales/budgets.en.yml b/config/locales/budgets.en.yml index 5e4861a16..7b3251ad4 100644 --- a/config/locales/budgets.en.yml +++ b/config/locales/budgets.en.yml @@ -25,11 +25,11 @@ en: unfeasible_title: Unfeasible investments unfeasible: See unfeasible investments phase: - accepting: Accepting proposals - reviewing: Reviewing proposals - selecting: Selecting proposals - valuating: Valuating proposals - balloting: Balloting proposals + accepting: Accepting projects + reviewing: Reviewing projects + selecting: Selecting projects + valuating: Valuating projects + balloting: Balloting projects reviewing_ballots: Reviewing Ballots finished: Finished budget index: diff --git a/config/locales/budgets.es.yml b/config/locales/budgets.es.yml index 08a33bde8..44b748698 100644 --- a/config/locales/budgets.es.yml +++ b/config/locales/budgets.es.yml @@ -25,13 +25,13 @@ es: unfeasible_title: Propuestas inviables unfeasible: Ver propuestas inviables phase: - accepting: Aceptando propuestas - reviewing: Revisando propuestas - selecting: Selección de propuestas - valuating: Evaluación de propuestas - balloting: Votación de propuestas - reviewing_ballots: Contando resultados - finished: Presupuesto terminado + accepting: Presentación de proyectos + reviewing: Revisión interna de proyectos + selecting: Fase de apoyos + valuating: Evaluación de proyectos + balloting: Votación final + reviewing_ballots: Votación finalizada + finished: Resultados index: title: Presupuestos participativos investments: diff --git a/config/locales/en.yml b/config/locales/en.yml index bc676128d..b6001a744 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -175,7 +175,6 @@ en: copyright: Consul, %{year} description: This portal uses the %{consul} which is %{open_source}. faq: technical assistance - more_info: More information open_data_text: Every detail about the City Council is yours to access. open_data_title: Open data open_source: open-source software @@ -192,16 +191,16 @@ en: debates: Debates external_link_blog: Blog external_link_opendata: Open data - external_link_opendata_url: "/opendata" + external_link_opendata_url: https://opendata.consul external_link_transparency: Transparency external_link_transparency_url: https://transparency.consul locale: 'Language:' - logo: Consul + logo: Consul logo management: Management moderation: Moderation valuation: Valuation officing: Polling officers - more_information: More information + more_info: More information my_account_link: My account my_activity_link: My activity notifications: Notifications @@ -388,6 +387,7 @@ en: share: Share send_notification: Send notification no_notifications: "This proposal has any notifications." + embed_video_title: "Video on %{proposal}" update: form: submit_button: Save changes @@ -481,6 +481,7 @@ en: search: 'Filter' title: 'Advanced search' to: 'To' + delete: Delete author_info: author_deleted: User deleted back: Go back @@ -525,6 +526,8 @@ en: facebook: Facebook twitter: Twitter youtube: YouTube + whatsapp: WhatsApp + telegram: Telegram spending_proposals: form: association_name_label: 'If you propose in name of an assocation or collective add the name here' diff --git a/config/locales/es.yml b/config/locales/es.yml index cae74281d..7d942a1e6 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -175,7 +175,6 @@ es: copyright: Consul, %{year} description: Este portal usa la %{consul} que es %{open_source}. faq: Asistencia técnica - more_info: Más información open_data_text: Todos los datos del Ayuntamiento son tuyos. open_data_title: Datos Abiertos open_source: software libre @@ -192,16 +191,16 @@ es: debates: Debates external_link_blog: Blog external_link_opendata: Datos abiertos - external_link_opendata_url: "/opendata" + external_link_opendata_url: https://opendata.consul external_link_transparency: Transparencia external_link_transparency_url: https://transparency.consul locale: 'Idioma:' - logo: Consul + logo: Consul logo management: Gestión moderation: Moderar valuation: Evaluación officing: Presidentes de mesa - more_information: Más información + more_info: Más información my_account_link: Mi cuenta my_activity_link: Mi actividad notifications: Notificaciones @@ -388,6 +387,7 @@ es: send_notification: Enviar notificación share: Compartir no_notifications: "Esta propuesta no tiene notificaciones." + embed_video_title: "Vídeo en %{proposal}" update: form: submit_button: Guardar cambios @@ -481,6 +481,7 @@ es: search: 'Filtrar' title: 'Búsqueda avanzada' to: 'Hasta' + delete: 'Borrar' author_info: author_deleted: Usuario eliminado back: Volver @@ -525,6 +526,8 @@ es: facebook: Facebook twitter: Twitter youtube: YouTube + whatsapp: WhatsApp + telegram: Telegram spending_proposals: form: association_name_label: 'Si propones en nombre de una asociación o colectivo añade el nombre aquí' @@ -620,8 +623,8 @@ es: one: 1 Propuesta other: "%{count} Propuestas" budget_investments: - one: 1 Propuesta de inversión - other: "%{count} Propuestas de inversión" + one: 1 Proyecto de presupuestos participativos + other: "%{count} Proyectos de presupuestos participativos" no_activity: Usuario sin actividad pública no_private_messages: "Este usuario no acepta mensajes privados." private_activity: Este usuario ha decidido mantener en privado su lista de actividades diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 596531c0d..74a65a916 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -854,7 +854,6 @@ fr: description: Ce portail utiliser %{consul} qui est %{open_source}. De Madrid ouvert sur le monde. faq: assistance technique - more_info: Plus d'information open_data_text: Tout les détails de la Mairie sont vôtre pour accès open_data_title: Open data open_source: logiciel libre @@ -874,9 +873,9 @@ fr: external_link_transparency: Transparence external_link_transparency_url: https://transparency.consul locale: 'Langue :' - logo: Consul + logo: Consul logo moderation: Modération - more_information: Plus d'information + more_info: Plus d'information my_account_link: Mon compte my_activity_link: Mon activité new_notifications: @@ -1167,7 +1166,7 @@ fr: mentionnées dans les conditions d'utilisation de ce portail." conditions: Conditions d'utilisation general_terms: Conditions d'utilisation - more_information: + more_info: description: faq: Questions fréquentes sur les problèmes techniques how_it_works: Découvrez tout ce qui est possible de faire avec ce site @@ -1232,7 +1231,7 @@ fr: titles: accessibility: Accessibilité conditions: Conditions d'utilisation - more_information: Plus d'informations + more_info: Plus d'informations opendata: Open Data privacy: Vie privée verify: @@ -1354,7 +1353,8 @@ fr: official_level_3_name: Niveau 3 personne officielle official_level_4_name: Niveau 4 personne officielle official_level_5_name: Niveau 5 personne officielle - per_page_code: Code à inclure dans chaque page + per_page_code_head: "Code à inclure dans chaque page ()" + per_page_code_body: "Code à inclure dans chaque page ()" proposal_code_prefix: Préfixe pour les codes de propositions votes_for_proposal_success: Nombre de votes nécessaires pour l'approbation d'une proposition @@ -1395,6 +1395,8 @@ fr: facebook: Facebook twitter: Twitter youtube: YouTube + whatsapp: WhatsApp + telegram: Telegram social_share_button: baidu: Baidu.com delicious: Delicious @@ -1413,6 +1415,7 @@ fr: tumblr: Tumblr twitter: Twitter weibo: Sina Weibo + telegram: Telegram spending_proposals: form: description: Description @@ -1629,7 +1632,7 @@ fr: link: Voir les propositions text: Créez vos propres propositions et soutenez celles d'autres citoyens. title: Propositions citoyennes - more_information: Plus d'information sur cette page + more_info: Plus d'information sur cette page proposal: alt: Icône Proposez description: Espace ouvert aux propositions sur le type de ville que nous voulons diff --git a/config/locales/management.en.yml b/config/locales/management.en.yml index 25032010e..d8aaf826c 100644 --- a/config/locales/management.en.yml +++ b/config/locales/management.en.yml @@ -32,6 +32,7 @@ en: under_age: "You don't have the required age to verify your account." verify: Verify email_label: Email + date_of_birth: Date of birth email_verifications: already_verified: This user account is already verified. choose_options: 'Please choose one of the following options:' diff --git a/config/locales/management.es.yml b/config/locales/management.es.yml index 9ac276f3a..10543798a 100644 --- a/config/locales/management.es.yml +++ b/config/locales/management.es.yml @@ -32,6 +32,7 @@ es: under_age: No tienes edad suficiente para verificar tu cuenta. verify: Verificar usuario email_label: Email + date_of_birth: Fecha de nacimiento email_verifications: already_verified: Esta cuenta de usuario ya está verificada. choose_options: 'Elige una de las opciones siguientes:' diff --git a/config/locales/pages.en.yml b/config/locales/pages.en.yml index 4ac76b1d3..a8e8a1b47 100755 --- a/config/locales/pages.en.yml +++ b/config/locales/pages.en.yml @@ -4,42 +4,52 @@ en: census_terms: To confirm the account, you must be 16 or older and be registered, having provided the information requested previously, will verify. By accepting the verification process, you also consent to the verification of this information, as well as the contact methods featuring in said files. The data provided will be acquired and processed in a file mentioned previously in the terms and conditions of use for the Portal. conditions: Terms and conditions of use general_terms: Terms and Conditions - more_information: - description: - faq: Frecuently asked question about tecnical problems - how_it_works: Find out all you can do with this web site - how_to_use: Use it freely or help us to improve it, it is free software - participation: Citizen participation, transparency and open government - participation_facts: To lose your fear - participation_world: Systems of citizen participation that exist in the world - proposals_info: Create your own proposals - signature_sheet: Sheet collecting signatures for support - spending_proposals_info: Create your own spending proposals - how_it_works: - i: Participation - i1: Debates area - i2: Proposals area - text: |- - The new Open Government Portal is divided in three parts: Participation, Transparency and Open Data (you can see the links in the upper right-hand part). - >**I. Participation:** In this part we can decide which city we want (using citizen proposals, debate areas, participatory budgets , collaborative legislation, and many others we will implement). - **II. Transparency:** In this part information about how the city is managed will be published every day: name, position, salary, contracts, agenda,... of the persons in charge. It is also the place where exercise your right to access information, having the chance to request any information about City Council easily and rapidly. - **III. Open data:** In this part the city council databases are posted, so that anyone can use information directly, without having to ask. It can also be requested the publication of more databases. - - We have opened the new Participation portal and we will open the new Transparency and Open Data seccion shortly (meanwhile the links to existing sites are kept). - ## I. Participation - The participation section will have different ways to participate: citizen proposals, debate areas, participatory budgets , collaborative legislation, and many others. You can currently visit the debate area and the citizen proposals will be ready very soon. - ## I.I. Debates area - In the debates area everyone can open a discussion thread about any topic, creating an independent space where people could debate about the proposed topic. In this way, in this digital space there will be hundreds of different debate spaces which citizens could see, joining the ones they find more interesting. - - Both threads and comments could be valued by anyone, so the citizenship, and not someone in its name, will decide which are the most important issues in every moment. These will be showed in the main page of the space, being able to access also the rest of issues in following pages, or using others order criteria (the most commented, the newst, the most controversial, etc.). - - Every city council employee has its own user, which will be designated as such, allowing them to participate in debates at the same level than the rest of citizens. That will allow creating direct communication spaces between them, avoiding the problems that implies the measured communication, and following clear approach of the new City Council by virtue of which the city council works for the citizenship. - ## I.I. Proposals area - In the proposals area everyone can propose an initiative with the intention of collecting support enough for the idea being consulting to the whole citizenship with binding effect. - - The proposals can be supported by every citizen registered that has verified their account in the participation platform. In this way, the citizenship, and not someone in its name, will decide which are the proposals that are worthwhile to carry out. - - One that the proposal has achive support of 1% census, it will be studied by a city council group and to move beyond the popular referendum phase, in which citizenship will vote if it is carried out or not. The maximum period to obtain support enough is 12 months. + more_info: + title: "Discover %{org_name}" + subtitle: "Learn everything you can do on this website." + guide: 'This guide explains each section of %{org_name}. You can expand the information on "Detailed information" links.' + menu: + debates: "Debates" + proposals: "Proposals" + budgets: "Participatory budgets" + other: "Other information of interest" + debates: + title: "Debates" + description: "Create a thread where you can discuss any topic you want to share with other people in your city." + feature_1: "To create a debate you have to %{link}" + feature_1_link: "sign up on %{org_name}" + feature_2_html: "Debates can be rated using the I agree or I disagree buttons you'll find on each of them." + image_alt: "Buttons to rate the debates" + figcaption: '"I agree" and "I disagree" buttons to rate the debates.' + proposals: + title: "Proposals" + description: "Propose what you want the City Council to carry out and support proposals from other people." + detail: "Detailed information of proposals" + feature_1: "To create a proposal you have to %{link}, in addition to support you must verify your account." + feature_1_link: "sign up on %{org_name}" + feature_2_html: "Proposals that get support from 1% of people will be voted on." + feature_3_html: "If there are more people in favor of against, the City Council assumes the proposal and it is done." + image_alt: "Button to support a proposal" + figcaption_html: 'Button to "Support" a proposal.
    When it reaches the number of supports will go to vote.' + budgets: + title: "Participatory Budgeting" + description: "The first six months of each year you can decide how to spend part of the budget." + detail: "Detailed information of Participatory Budgeting" + feature_1: "To create an investment project you have to %{link} and verify your account." + feature_1_link: "sign up on %{org_name}" + feature_2_html: "The first is the accepting phase of investment projects." + feature_3_html: "Then there is a support phase to prioritize the most interesting, the most supported are evaluated by the City to see if they are viable and how much they are worth." + feature_4_html: "At the end there is a voting phase where it is decided on which part of the budget is spent." + image_alt: "Different phases of a participatory budget" + figcaption_html: '"Support phase" and "Voting" phase of participatory budgets.' + faq: + title: "Technical problems?" + description: "Read the FAQs and solve your questions." + button: "View frequently asked questions" + other: + how_to_use: "Use %{org_name} in your city" + world: "Citizen participation in the world" + facts: "Facts about citizen participation and direct democracy" how_to_use: text: |- Use it in your local government or help us to improve it, it is free software. @@ -48,24 +58,12 @@ en: If you are a programmer, you can see the code and help us to improve it at [Consul app](https://github.com/ayuntamientomadrid 'consul github'). titles: - faq: Solution to tecnical problemas (FAQ) - how_it_works: How does this Open Government Portal work? how_to_use: Use it in your local government - participation: Participation and Transparency y Transparencia - coming news - participation_facts: Facts about citizen participation and direct democracy - participation_world: Direct citizen participation in the world - proposals_info: How does citizen proposals work? - signature_sheet: Signature sheet - spending_proposals_info: How does participatory budgeting work? - opendata: - slogan: "Information about Open Data." - title: Open Data privacy: Privacy Policy titles: accessibility: Accessibility conditions: Terms of use - more_information: More information - opendata: Open Data + more_info: "More information about %{org_name}" privacy: Privacy Policy verify: code: Code you received in letter @@ -74,4 +72,4 @@ en: info_code: 'Now introduce the code you received in letter:' password: Password submit: Verify my account - title: Verify your account + title: Verify your account \ No newline at end of file diff --git a/config/locales/pages.es.yml b/config/locales/pages.es.yml index e3e82effa..652f03852 100644 --- a/config/locales/pages.es.yml +++ b/config/locales/pages.es.yml @@ -4,42 +4,52 @@ es: census_terms: Para verificar la cuenta hay que tener 16 años o más y estar empadronado aportando los datos indicados anteriormente, los cuales serán contrastados. Aceptando el proceso de verificación acepta dar su consentimiento para contrastar dicha información, así como medios de contacto que figuren en dichos ficheros. Los datos aportados serán incorporados y tratados en un fichero indicado anteriormente en las condiciones de uso del portal. conditions: Condiciones de uso general_terms: Términos y Condiciones - more_information: - description: - faq: Preguntas frecuentes sobre problemas técnicos - how_it_works: Descubre todo lo que puedes hacer en esta web - how_to_use: Utilízalo libremente o ayúdanos a mejorarlo, es software libre - participation: Participación Ciudadana, Transparencia y Gobierno Abierto - participation_facts: Para perderle el miedo - participation_world: Sistemas de participación ciudadana que ya existen en el mundo - proposals_info: Crea tus propias propuestas - signature_sheet: Hojas de firmas para recoger apoyos - spending_proposals_info: Envía tus propuestas de gasto - how_it_works: - i: Participación - i1: Espacio de debate - i2: Espacio de propuestas - text: |- - El nuevo Portal de Gobierno Abierto está dividido en tres partes: Participación, Transparencia y Datos Abiertos (verás los enlaces en la parte superior derecha). - >**I. Participación:** Donde poder decidir qué ciudad queremos tener (a través de propuestas ciudadanas, espacios de debate, presupuestos participativos, legislación colaborativa, y muchos otros procesos que iremos implementando). - **II. Transparencia:** En este espacio se publicarán todos los datos relativos a quién y cómo se gestiona la ciudad (nombres de los responsables, cargos, sueldos, planes de gobierno, contratos, agendas de los responsables...). Además es el espacio donde ejercer el derecho de acceso a la información, pudiendo solicitar cualquier información sobre el Ayuntamiento de manera fácil y rápida. - **III. Datos Abiertos:** En este espacio se cuelgan las bases de datos que tiene el Ayuntamiento, para que cualquiera pueda usar toda la información directamente, sin necesidad ni siquiera de preguntar. También se puede solicitar la publicación de más bases de datos. - - Inauguramos el nuevo portal con la nueva sección de Participación, y en breve añadiremos las nuevas secciones de Transparencia y Datos Abiertos (así que mantenemos por el momento los enlaces a las páginas al respecto que ya existían). - ## I. Participación - El apartado de participación comprenderá diferentes mecanismos de participación: propuestas ciudadanas, espacios de debate, presupuestos participativos, legislación colaborativa, entre muchos otros. Por el momento presentamos el espacio de debate, y muy pronto las propuestas ciudadanas. - ## I.I. Espacio de debate - En este espacio, cualquier persona puede abrir un hilo de discusión sobre cualquier tema, creando un espacio independiente donde la gente podrá debatir sobre el tema propuesto. De esta manera, en este espacio digital convivirán cada día cientos de espacios de debate distintos entre los que la ciudadanía podrá pasearse, sumándose a los que más les interese. - - Tanto los hilos, como los comentarios podrán ser valorados por cualquiera, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son los temas más importantes en cada momento. Estos serán presentados en la portada del espacio, pudiendo por supuesto accederse a todos los demás temas en páginas posteriores, o usando otros criterios de ordenación (los temas con más comentarios, los más nuevos, los más controvertidos, etc.). - - Cada uno de los trabajadores del Ayuntamiento tiene un usuario propio, que será resaltado como tal, permitiendo que participen en los debates al mismo nivel que todos los demás ciudadanos. Esto permitirá crear espacios de comunicación directos entre unos y otros, evitando los inconvenientes que implica la comunicación mediada, y respondiendo a un planteamiento claro por parte del nuevo gobierno por el cual el Ayuntamiento trabaja para la ciudadanía, y ante ella debe responder. - ## I.I. Espacio de propuestas - En este espacio, cualquier persona puede proponer una iniciativa con la intención de recabar los suficientes apoyos como para que la idea pase a ser consultada a toda la ciudadanía con carácter vinculante. - - Las propuestas pueden ser apoyadas por ciudadanos empadronados que hayan verificado su cuenta en la plataforma de participación, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son las propuestas que merecen la pena ser llevadas a cabo. - - Una vez que una propuesta alcance una cantidad de apoyos equivalente al 1% del censo, automáticamente pasa a ser estudiada por un grupo de trabajo del Ayuntamiento y pasará a la siguiente fase de consulta popular, en la que la ciudadanía votará si se lleva a cabo o no. El plazo máximo para recabar los apoyos necesarios será de 12 meses. + more_info: + title: "Descubre %{org_name}" + subtitle: "Aprende todo lo que puedes hacer en esta web." + guide: 'Esta guía explica cada una de las secciones de %{org_name}. Puedes ampliar la información en los enlaces de "Información detallada".' + menu: + debates: "Debates" + proposals: "Propuestas" + budgets: "Presupuestos participativos" + other: "Otra información de interés" + debates: + title: "Debates" + description: "Crea un hilo en el que debatir sobre cualquier tema que quieras compartir con el resto de gente de tu ciudad." + feature_1: "Para crear un debate tienes que %{link}" + feature_1_link: "registrarte en %{org_name}" + feature_2_html: "Los debates pueden ser valorados utilizando los botones de Estoy de acuerdo o No estoy de acuerdo que encontrarás en cada uno de ellos." + image_alt: "Botones para valorar los debates" + figcaption: 'Botones "Estoy de acuerdo" y "No estoy de acuerdo" para valorar los debates.' + proposals: + title: "Propuestas" + description: "Propón lo que quieres que el Ayuntamiento lleve a cabo y apoya propuestas de otras personas." + detail: "Información detallada de Propuestas" + feature_1: "Para crear una propuesta tienes que %{link}, además para apoyarlas debes verificar tu cuenta." + feature_1_link: "registrarte en %{org_name}" + feature_2_html: "Las propuestas que consigan el apoyo del 1% de la gente (mayor de 16 años empadronada en Madrid; 27.064 apoyos) pasan a votación." + feature_3_html: "Si hay más gente a favor que en contra en la votación, el Ayuntamiento asume la propuesta y se hace." + image_alt: "Botón para apoyar una propuesta" + figcaption_html: 'Botón para "Apoyar" una propuesta.
    Cuando alcance el número de apoyos pasará a votación.' + budgets: + title: "Presupuestos participativos" + description: "Los primeros seis meses de cada año puedes decidir cómo gastar parte del presupuesto." + detail: "Información detallada de Presupuestos participativos" + feature_1: "Para crear un proyecto de gasto tienes que %{link} y verificar tu cuenta." + feature_1_link: "registrarte en %{org_name}" + feature_2_html: "En primer lugar empieza la fase de aceptación de proyectos de gasto." + feature_3_html: "Después hay una fase de apoyos para priorizar lo más interesante, las más apoyadas son evaluadas por el Ayuntamiento para ver si son viables y cuánto valen." + feature_4_html: "Al final hay una fase de votación donde se decide en cuáles se gasta esa parte del presupuesto." + image_alt: "Diferentes fases de un presupuesto participativo" + figcaption_html: 'Fase de "Apoyos" y fase de "Votación" de los presupuestos participativos.' + faq: + title: "¿Problemas técnicos?" + description: "Lee las preguntas frecuentes y resuelve tus dudas." + button: "Ver preguntas frecuentes" + other: + how_to_use: "Utiliza %{org_name} en tu municipio" + world: "Participación ciudadana directa en el mundo" + facts: "Hechos sobre participación ciudadana y democracia directa" how_to_use: text: |- Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre. @@ -48,24 +58,12 @@ es: Si eres programador, puedes ver el código y ayudarnos a mejorarlo en [aplicación Consul](https://github.com/ayuntamientomadrid 'github consul'). titles: - faq: Soluciones a problemas técnicos (FAQ) - how_it_works: "¿Cómo funciona este Portal de Gobierno Abierto?" how_to_use: Utilízalo en tu municipio - participation: Participación y Transparencia - Próximas novedades - participation_facts: Hechos sobre participación ciudadana y democracia directa - participation_world: Participación ciudadana directa en el mundo - proposals_info: "¿Cómo funcionan las propuestas ciudadanas?" - signature_sheet: Hojas de firmas - spending_proposals_info: "¿Cómo funcionan los presupuestos participativos?" - opendata: - slogan: "Información sobre Datos abiertos." - title: Datos abiertos privacy: Política de Privacidad titles: accessibility: Accesibilidad conditions: Condiciones de uso - more_information: Más información - opendata: Datos abiertos + more_info: "Más información sobre %{org_name}" privacy: Política de Privacidad verify: code: Código que has recibido en tu carta @@ -74,4 +72,4 @@ es: info_code: 'Ahora introduce el código que has recibido en tu carta:' password: Contraseña submit: Verificar mi cuenta - title: Verifica tu cuenta + title: Verifica tu cuenta \ No newline at end of file diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 75e7aebb6..298d536ab 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -841,7 +841,6 @@ pt-BR: description: Este portal usa o %{consul} que é %{open_source}. De Madrid para o mundo. faq: suporte técnico - more_info: Mais informações open_data_text: Todos os detalhes sobre a Câmara estão disponíveis para acesso. open_data_title: Dados abertos open_source: programa de código aberto @@ -860,9 +859,9 @@ pt-BR: external_link_transparency: Transparência external_link_transparency_url: https://transparency.consul locale: 'Idioma:' - logo: Consul + logo: Consul logotipo moderation: Moderação - more_information: Mais informações + more_info: Mais informações my_account_link: Minha conta my_activity_link: Minha atividade new_notifications: @@ -1149,7 +1148,7 @@ pt-BR: mencionado previamente nos termos e condições de uso deste Portal. conditions: Termos e condições de uso general_terms: Termos e condições - more_information: + more_info: description: faq: Perguntas frequentes feitas sobre problemas técnicos how_it_works: Descubra tudo que você pode fazer com este website. @@ -1248,7 +1247,7 @@ pt-BR: titles: accessibility: Acessibilidade conditions: Termos de uso - more_information: Mais informações + more_info: Mais informações opendata: Dados abertos privacy: Política de privacidade verify: @@ -1370,7 +1369,8 @@ pt-BR: official_level_3_name: Nível 3 coordenador público official_level_4_name: Nível 4 coordenador público official_level_5_name: Nível 5 coordenador público - per_page_code: Código a ser incluído em cada página + per_page_code_head: "Código a ser incluído em cada página ()" + per_page_code_body: "Código a ser incluído em cada página ()" proposal_code_prefix: Prefixo para códigos de Proposta votes_for_proposal_success: Número de votos necessários para aprovar uma Proposta shared: @@ -1640,7 +1640,7 @@ pt-BR: link: Mostrar propostas text: Criar suas próprias propostas e apoiar aquelas de outros cidadãos title: Propostas cidadãs - more_information: Mais informações sobre esta página + more_info: Mais informações sobre esta página proposal: alt: "Ícone proposta" description: Espaço aberto para propostas cidadãs sobre o tipo de cidade dentro da qual nós queremos viver. diff --git a/config/locales/settings.en.yml b/config/locales/settings.en.yml index 249b5df3e..987c9e7fe 100755 --- a/config/locales/settings.en.yml +++ b/config/locales/settings.en.yml @@ -13,7 +13,8 @@ en: votes_for_proposal_success: "Number of votes necessary for approval of a Proposal" months_to_archive_proposals: "Months to archive Proposals" email_domain_for_officials: "Email domain for public officials" - per_page_code: "Code to be included on every page" + per_page_code_head: "Code to be included on every page ()" + per_page_code_body: "Code to be included on every page ()" twitter_handle: "Twitter handle" twitter_hashtag: "Twitter hashtag" facebook_handle: "Facebook handle" diff --git a/config/locales/settings.es.yml b/config/locales/settings.es.yml index 9ec679051..9e15bc6eb 100644 --- a/config/locales/settings.es.yml +++ b/config/locales/settings.es.yml @@ -13,7 +13,8 @@ es: votes_for_proposal_success: "Número de votos necesarios para aprobar una Propuesta" months_to_archive_proposals: "Meses para archivar las Propuestas" email_domain_for_officials: "Dominio de email para cargos públicos" - per_page_code: "Código a incluir en cada página" + per_page_code_head: "Código a incluir en cada página ()" + per_page_code_body: "Código a incluir en cada página ()" twitter_handle: "Usuario de Twitter" twitter_hashtag: "Hashtag para Twitter" facebook_handle: "Identificador de Facebook" diff --git a/config/locales/social_share_button.en.yml b/config/locales/social_share_button.en.yml index b06cb5ad3..2715c46ab 100644 --- a/config/locales/social_share_button.en.yml +++ b/config/locales/social_share_button.en.yml @@ -17,3 +17,4 @@ en: plurk: "Plurk" pinterest: "Pinterest" email: "Email" + telegram: "Telegram" diff --git a/config/locales/social_share_button.es.yml b/config/locales/social_share_button.es.yml index 45e4ab2a5..1c49ef4f5 100644 --- a/config/locales/social_share_button.es.yml +++ b/config/locales/social_share_button.es.yml @@ -17,3 +17,4 @@ es: plurk: "Plurk" pinterest: "Pinterest" email: "Correo electrónico" + telegram: "Telegram" diff --git a/config/routes.rb b/config/routes.rb index cc2944ad3..48062f779 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -329,7 +329,7 @@ Rails.application.routes.draw do get :support_investments get :print_investments end - resources :investments, only: [:index, :new, :create, :show], controller: 'budgets/investments' do + resources :investments, only: [:index, :new, :create, :show, :destroy], controller: 'budgets/investments' do post :vote, on: :member get :print, on: :collection end @@ -355,6 +355,15 @@ Rails.application.routes.draw do mount Tolk::Engine => '/translate', :as => 'tolk' + # more info pages + get 'more-information', to: 'pages#show', id: 'more_info/index', as: 'more_info' + get 'more-information/how-to-use', to: 'pages#show', id: 'more_info/how_to_use/index', as: 'how_to_use' + get 'more-information/faq', to: 'pages#show', id: 'more_info/faq/index', as: 'faq' + get 'more-information/proposals', to: 'pages#show', id: 'more_info/proposals/index', as: 'more_info_proposals' + get 'more-information/budgets', to: 'pages#show', id: 'more_info/budgets/index', as: 'more_info_budgets' + get 'more-information/participation/facts', to: 'pages#show', id: 'more_info/participation/facts', as: 'participation_facts' + get 'more-information/participation/world', to: 'pages#show', id: 'more_info/participation/world', as: 'participation_world' + # static pages get '/blog' => redirect("http://blog.consul/") resources :pages, path: '/', only: [:show] diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 9ed75176e..9c37b4f7b 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -33,7 +33,8 @@ Setting.create(key: 'feature.twitter_login', value: "true") Setting.create(key: 'feature.facebook_login', value: "true") Setting.create(key: 'feature.google_login', value: "true") Setting.create(key: 'feature.signature_sheets', value: "true") -Setting.create(key: 'per_page_code', value: "") +Setting.create(key: 'per_page_code_head', value: "") +Setting.create(key: 'per_page_code_body', value: "") Setting.create(key: 'comments_body_max_length', value: '1000') Setting.create(key: 'mailer_from_name', value: 'Consul') Setting.create(key: 'mailer_from_address', value: 'noreply@consul.dev') @@ -422,7 +423,7 @@ end puts " ✅" print "Creating Valuation Assignments" -(1..17).to_a.sample.times do +(1..50).to_a.sample.times do Budget::Investment.reorder("RANDOM()").first.valuators << valuator.valuator end diff --git a/db/seeds.rb b/db/seeds.rb index 70fccb177..3ef166bc7 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -38,14 +38,18 @@ Setting["months_to_archive_proposals"] = 12 # Emails under the domain's subdomains will also be included Setting["email_domain_for_officials"] = '' -# Code to be included at the top (header) of every page (useful for tracking) -Setting['per_page_code'] = '' +# Code to be included at the top (inside ) of every page (useful for tracking) +Setting['per_page_code_head'] = '' + +# Code to be included at the top (inside ) of every page +Setting['per_page_code_body'] = '' # Social settings Setting["twitter_handle"] = nil Setting["twitter_hashtag"] = nil Setting["facebook_handle"] = nil Setting["youtube_handle"] = nil +Setting["telegram_handle"] = nil Setting["blog_url"] = nil # Public-facing URL of the app. diff --git a/public/404.html b/public/404.html index cc6820bba..5b5362192 100644 --- a/public/404.html +++ b/public/404.html @@ -1,5 +1,5 @@ - + Error 404 | Not found diff --git a/public/422.html b/public/422.html index e68d2956f..cca90e5a3 100644 --- a/public/422.html +++ b/public/422.html @@ -1,5 +1,5 @@ - + Error 422 | The change you wanted was rejected diff --git a/public/500.html b/public/500.html index 71978cdce..0b563452a 100644 --- a/public/500.html +++ b/public/500.html @@ -1,5 +1,5 @@ - + Error 500 | Internal server error diff --git a/spec/controllers/pages_controller_spec.rb b/spec/controllers/pages_controller_spec.rb index eed930a57..b72bf032e 100644 --- a/spec/controllers/pages_controller_spec.rb +++ b/spec/controllers/pages_controller_spec.rb @@ -22,38 +22,37 @@ describe PagesController do get :show, id: :census_terms expect(response).to be_ok end - end - describe 'Provisional pages' do - it 'should include a opendata page' do - get :show, id: :opendata + it 'should include a accessibility page' do + get :show, id: :accessibility expect(response).to be_ok end end - describe 'Info pages' do - it 'should include a how_it_works page' do - get :show, id: :how_it_works + describe 'More info pages' do + + it 'should include a more info page' do + get :show, id: 'more_info/index' expect(response).to be_ok end it 'should include a how_to_use page' do - get :show, id: :how_to_use + get :show, id: 'more_info/how_to_use/index' expect(response).to be_ok end - it 'should include a more_information page' do - get :show, id: :more_information + it 'should include a faq page' do + get :show, id: 'more_info/faq/index' expect(response).to be_ok end - it 'should include a participation page' do - get :show, id: :participation + it 'should include a participation facts page' do + get :show, id: 'more_info/participation/facts' expect(response).to be_ok end - it 'should include a accessibility page' do - get :show, id: :accessibility + it 'should include a participation world page' do + get :show, id: 'more_info/participation/world' expect(response).to be_ok end end diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index ede09ec4f..f4dde2425 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -252,6 +252,21 @@ feature 'Admin budget investments' do expect(page).to have_content("More schools") end + scenario "Filtering by tag, display only valuation tags" do + investment1 = create(:budget_investment, budget: @budget, tag_list: 'Education') + investment2 = create(:budget_investment, budget: @budget, tag_list: 'Health') + + investment1.set_tag_list_on(:valuation, 'Teachers') + investment2.set_tag_list_on(:valuation, 'Hospitals') + + investment1.save + investment2.save + + visit admin_budget_budget_investments_path(budget_id: @budget.id) + + expect(page).to have_select("tag_name", options: ["All tags", "Hospitals", "Teachers"]) + end + end scenario 'Show' do diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 3b34878af..c93aebea1 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -84,7 +84,7 @@ feature 'Admin budgets' do fill_in 'budget_name', with: 'M30 - Summer campaign' fill_in 'budget_description_accepting', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30' - select 'Accepting proposals', from: 'budget[phase]' + select 'Accepting projects', from: 'budget[phase]' click_button 'Create Participatory budget' diff --git a/spec/features/admin/signature_sheets_spec.rb b/spec/features/admin/signature_sheets_spec.rb index 8243dd913..bcde7bfc0 100644 --- a/spec/features/admin/signature_sheets_spec.rb +++ b/spec/features/admin/signature_sheets_spec.rb @@ -19,20 +19,42 @@ feature 'Signature sheets' do end end - scenario 'Create' do - proposal = create(:proposal) - visit new_admin_signature_sheet_path + context 'Create' do + scenario 'Proposal' do + proposal = create(:proposal) + visit new_admin_signature_sheet_path - select "Citizen proposal", from: "signature_sheet_signable_type" - fill_in "signature_sheet_signable_id", with: proposal.id - fill_in "signature_sheet_document_numbers", with: "12345678Z, 99999999Z" - click_button "Create signature sheet" + select "Citizen proposal", from: "signature_sheet_signable_type" + fill_in "signature_sheet_signable_id", with: proposal.id + fill_in "signature_sheet_document_numbers", with: "12345678Z, 99999999Z" + click_button "Create signature sheet" - expect(page).to have_content "Signature sheet created successfully" + expect(page).to have_content "Signature sheet created successfully" - visit proposal_path(proposal) + visit proposal_path(proposal) + + expect(page).to have_content "1 support" + end + + scenario 'Budget Investment' do + investment = create(:budget_investment) + budget = investment.budget + budget.update(phase: 'selecting') + + visit new_admin_signature_sheet_path + + select "Investment", from: "signature_sheet_signable_type" + fill_in "signature_sheet_signable_id", with: investment.id + fill_in "signature_sheet_document_numbers", with: "12345678Z, 99999999Z" + click_button "Create signature sheet" + + expect(page).to have_content "Signature sheet created successfully" + + visit budget_investment_path(budget, investment) + + expect(page).to have_content "1 support" + end - expect(page).to have_content "1 support" end scenario 'Errors on create' do diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index a6feb6f44..5446e0a0a 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -315,6 +315,20 @@ feature 'Budget Investments' do end end + scenario "Author can destroy while on the accepting phase" do + user = create(:user, :level_two) + sp1 = create(:budget_investment, heading: heading, price: 10000, author: user) + + login_as(user) + visit user_path(user, tab: :budget_investments) + + within("#budget_investment_#{sp1.id}") do + expect(page).to have_content(sp1.title) + click_link('Delete') + end + + visit user_path(user, tab: :budget_investments) + end end context "Selecting Phase" do @@ -391,7 +405,7 @@ feature 'Budget Investments' do budget.update(phase: "valuating") end - scenario "Sidebar in show should display supports text and supports" do + scenario "Sidebar in show should display support text and count" do investment = create(:budget_investment, :selected, budget: budget) create(:vote, votable: investment) @@ -403,8 +417,8 @@ feature 'Budget Investments' do end end - scenario "Index should display supports" do - investment = create(:budget_investment, :selected, budget: budget, heading: heading) + scenario "Index should display support count" do + investment = create(:budget_investment, budget: budget, heading: heading) create(:vote, votable: investment) visit budget_investments_path(budget, heading_id: heading.id) @@ -414,6 +428,18 @@ feature 'Budget Investments' do end end + scenario "Show should display support text and count" do + investment = create(:budget_investment, budget: budget, heading: heading) + create(:vote, votable: investment) + + visit budget_investment_path(budget, investment) + + within("#budget_investment_#{investment.id}") do + expect(page).to have_content "Supports" + expect(page).to have_content "1 support" + end + end + end context "Balloting Phase" do @@ -476,6 +502,8 @@ feature 'Budget Investments' do expect(page).to have_content "€10,000" end + + scenario "Sidebar in show should display vote text" do investment = create(:budget_investment, :selected, budget: budget) visit budget_investment_path(budget, investment) @@ -561,4 +589,4 @@ feature 'Budget Investments' do end end -end \ No newline at end of file +end diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index f16f416bf..f6efceea2 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -54,7 +54,7 @@ feature 'Debates' do expect(page.html).to include "#{debate.title}" within('.social-share-button') do - expect(page.all('a').count).to be(3) # Twitter, Facebook, Google+ + expect(page.all('a').count).to be(4) # Twitter, Facebook, Google+, Telegram end end @@ -640,6 +640,28 @@ feature 'Debates' do end end + scenario "Search by custom invalid date range", :js do + debate1 = create(:debate, created_at: 2.years.ago) + debate2 = create(:debate, created_at: 3.days.ago) + debate3 = create(:debate, created_at: 9.days.ago) + + visit debates_path + + click_link "Advanced search" + select "Customized", from: "js-advanced-search-date-min" + fill_in "advanced_search_date_min", with: "9" + fill_in "advanced_search_date_max", with: "444444444" + click_button "Filter" + + within("#debates") do + expect(page).to have_css('.debate', count: 3) + + expect(page).to have_content(debate1.title) + expect(page).to have_content(debate2.title) + expect(page).to have_content(debate3.title) + end + end + scenario "Search by multiple filters", :js do ana = create :user, official_level: 1 john = create :user, official_level: 1 diff --git a/spec/features/management/budget_investments_spec.rb b/spec/features/management/budget_investments_spec.rb index 5b3961306..c4d7a8797 100644 --- a/spec/features/management/budget_investments_spec.rb +++ b/spec/features/management/budget_investments_spec.rb @@ -137,6 +137,61 @@ feature 'Budget Investments' do end end + scenario "Listing - managers can see budgets in accepting phase" do + accepting_budget = create(:budget, phase: "accepting") + reviewing_budget = create(:budget, phase: "reviewing") + selecting_budget = create(:budget, phase: "selecting") + valuating_budget = create(:budget, phase: "valuating") + balloting_budget = create(:budget, phase: "balloting") + reviewing_ballots_budget = create(:budget, phase: "reviewing_ballots") + finished = create(:budget, phase: "finished") + + user = create(:user, :level_two) + login_managed_user(user) + + click_link "Create budget investment" + + expect(page).to have_content(accepting_budget.name) + + expect(page).to_not have_content(reviewing_budget.name) + expect(page).to_not have_content(selecting_budget.name) + expect(page).to_not have_content(valuating_budget.name) + expect(page).to_not have_content(balloting_budget.name) + expect(page).to_not have_content(reviewing_ballots_budget.name) + expect(page).to_not have_content(finished.name) + end + + scenario "Listing - admins can see budgets in accepting, reviewing and selecting phases" do + accepting_budget = create(:budget, phase: "accepting") + reviewing_budget = create(:budget, phase: "reviewing") + selecting_budget = create(:budget, phase: "selecting") + valuating_budget = create(:budget, phase: "valuating") + balloting_budget = create(:budget, phase: "balloting") + reviewing_ballots_budget = create(:budget, phase: "reviewing_ballots") + finished = create(:budget, phase: "finished") + + visit root_path + click_link "Sign out" + + admin = create(:administrator) + login_as(admin.user) + + user = create(:user, :level_two) + login_managed_user(user) + visit management_sign_in_path + + click_link "Create budget investment" + + expect(page).to have_content(accepting_budget.name) + expect(page).to have_content(reviewing_budget.name) + expect(page).to have_content(selecting_budget.name) + + expect(page).to_not have_content(valuating_budget.name) + expect(page).to_not have_content(balloting_budget.name) + expect(page).to_not have_content(reviewing_ballots_budget.name) + expect(page).to_not have_content(finished.name) + end + context "Supporting" do scenario 'Supporting budget investments on behalf of someone in index view', :js do diff --git a/spec/features/management/users_spec.rb b/spec/features/management/users_spec.rb index 694720cc0..5d08ce711 100644 --- a/spec/features/management/users_spec.rb +++ b/spec/features/management/users_spec.rb @@ -18,6 +18,7 @@ feature 'Users' do fill_in 'user_username', with: 'pepe' fill_in 'user_email', with: 'pepe@gmail.com' + select_date '31-December-1980', from: 'user_date_of_birth' click_button 'Create user' @@ -28,6 +29,7 @@ feature 'Users' do expect(user).to be_level_three_verified expect(user).to be_residence_verified expect(user).to_not be_confirmed + expect(user.date_of_birth).to have_content (Date.new(1980,12,31)) sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1] visit user_confirmation_path(confirmation_token: sent_token) diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 0ef20d447..843b74bf5 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -63,7 +63,7 @@ feature 'Proposals' do expect(page.html).to include "#{proposal.title}" within('.social-share-button') do - expect(page.all('a').count).to be(3) # Twitter, Facebook, Google+ + expect(page.all('a').count).to be(4) # Twitter, Facebook, Google+, Telegram end end @@ -980,6 +980,28 @@ feature 'Proposals' do end end + scenario "Search by custom invalid date range", :js do + proposal1 = create(:proposal, created_at: 2.days.ago) + proposal2 = create(:proposal, created_at: 3.days.ago) + proposal3 = create(:proposal, created_at: 9.days.ago) + + visit proposals_path + + click_link "Advanced search" + select "Customized", from: "js-advanced-search-date-min" + fill_in "advanced_search_date_min", with: 4000.years.ago + fill_in "advanced_search_date_max", with: "wrong date" + click_button "Filter" + + expect(page).to have_content("There are 3 citizen proposals") + + within("#proposals") do + expect(page).to have_content(proposal1.title) + expect(page).to have_content(proposal2.title) + expect(page).to have_content(proposal3.title) + end + end + scenario "Search by multiple filters", :js do ana = create :user, official_level: 1 john = create :user, official_level: 1 diff --git a/spec/features/valuation/budget_investments_spec.rb b/spec/features/valuation/budget_investments_spec.rb index a3f5a1705..81e4eceae 100644 --- a/spec/features/valuation/budget_investments_spec.rb +++ b/spec/features/valuation/budget_investments_spec.rb @@ -13,6 +13,12 @@ feature 'Valuation budget investments' do expect{ visit valuation_budget_budget_investments_path(create(:budget)) }.to raise_exception(FeatureFlags::FeatureDisabled) end + scenario 'Display link to valuation section' do + Setting['feature.budgets'] = true + visit root_path + expect(page).to have_link "Valuation", href: valuation_root_path + end + scenario 'Index shows budget investments assigned to current valuator' do investment1 = create(:budget_investment, budget: @budget) investment2 = create(:budget_investment, budget: @budget) diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index d1eddcd51..7c02f50fd 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -15,12 +15,18 @@ describe "Abilities::Common" do let(:own_proposal) { create(:proposal, author: user) } let(:accepting_budget) { create(:budget, phase: 'accepting') } + let(:reviewing_budget) { create(:budget, phase: 'reviewing') } let(:selecting_budget) { create(:budget, phase: 'selecting') } let(:balloting_budget) { create(:budget, phase: 'balloting') } let(:investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget) } + let(:investment_in_reviewing_budget) { create(:budget_investment, budget: reviewing_budget) } let(:investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget) } let(:investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget) } + let(:own_investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget, author: user) } + let(:own_investment_in_reviewing_budget) { create(:budget_investment, budget: reviewing_budget, author: user) } + let(:own_investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget, author: user) } + let(:own_investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget, author: user) } let(:ballot_in_accepting_budget) { create(:budget_ballot, budget: accepting_budget) } let(:ballot_in_selecting_budget) { create(:budget_ballot, budget: selecting_budget) } let(:ballot_in_balloting_budget) { create(:budget_ballot, budget: balloting_budget) } @@ -191,12 +197,21 @@ describe "Abilities::Common" do it { should_not be_able_to(:vote, investment_in_accepting_budget) } it { should be_able_to(:vote, investment_in_selecting_budget) } it { should_not be_able_to(:vote, investment_in_balloting_budget) } + + it { should_not be_able_to(:destroy, investment_in_accepting_budget) } + it { should_not be_able_to(:destroy, investment_in_reviewing_budget) } + it { should_not be_able_to(:destroy, investment_in_selecting_budget) } + it { should_not be_able_to(:destroy, investment_in_balloting_budget) } + + it { should be_able_to(:destroy, own_investment_in_accepting_budget) } + it { should be_able_to(:destroy, own_investment_in_reviewing_budget) } + it { should_not be_able_to(:destroy, own_investment_in_selecting_budget) } + it { should_not be_able_to(:destroy, investment_in_balloting_budget) } it { should_not be_able_to(:create, ballot_in_accepting_budget) } it { should_not be_able_to(:create, ballot_in_selecting_budget) } it { should be_able_to(:create, ballot_in_balloting_budget) } end - end describe "when level 3 verified" do diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index abbc8ad26..fa51f3cab 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -35,7 +35,26 @@ describe Budget::Investment do expect(investment.description).to eq("alert('danger');") end - describe "#unfeasibility_explanation" do + it "set correct group and budget ids" do + budget = create(:budget) + group_1 = create(:budget_group, budget: budget) + group_2 = create(:budget_group, budget: budget) + + heading_1 = create(:budget_heading, group: group_1) + heading_2 = create(:budget_heading, group: group_2) + + investment = create(:budget_investment, heading: heading_1) + + expect(investment.budget_id).to eq budget.id + expect(investment.group_id).to eq group_1.id + + investment.update(heading: heading_2) + + expect(investment.budget_id).to eq budget.id + expect(investment.group_id).to eq group_2.id + end + + describe "#unfeasibility_explanation blank" do it "should be valid if valuation not finished" do investment.unfeasibility_explanation = "" investment.valuation_finished = false @@ -57,6 +76,29 @@ describe Budget::Investment do end end + describe "#price blank" do + it "should be valid if valuation not finished" do + investment.price = "" + investment.valuation_finished = false + expect(investment).to be_valid + end + + it "should be valid if valuation finished and unfeasible" do + investment.price = "" + investment.unfeasibility_explanation = "reason" + investment.feasibility = "unfeasible" + investment.valuation_finished = true + expect(investment).to be_valid + end + + it "should not be valid if valuation finished and feasible" do + investment.price = "" + investment.feasibility = "feasible" + investment.valuation_finished = true + expect(investment).to_not be_valid + end + end + describe "#code" do let(:investment) { create(:budget_investment) } @@ -285,6 +327,45 @@ describe Budget::Investment do expect(salamanca_investment.valid_heading?(user)).to eq(false) end + + it "allows votes in a group with a single heading" do + all_city_investment = create(:budget_investment, heading: heading) + expect(all_city_investment.valid_heading?(user)).to eq(true) + end + + it "allows votes in a group with a single heading after voting in that heading" do + all_city_investment1 = create(:budget_investment, heading: heading) + all_city_investment2 = create(:budget_investment, heading: heading) + + create(:vote, votable: all_city_investment1, voter: user) + + expect(all_city_investment2.valid_heading?(user)).to eq(true) + end + + it "allows votes in a group with a single heading after voting in another group" do + districts = create(:budget_group, budget: budget) + carabanchel = create(:budget_heading, group: districts) + + all_city_investment = create(:budget_investment, heading: heading) + carabanchel_investment = create(:budget_investment, heading: carabanchel) + + create(:vote, votable: carabanchel_investment, voter: user) + + expect(all_city_investment.valid_heading?(user)).to eq(true) + end + + it "allows votes in a group with multiple headings after voting in group with a single heading" do + districts = create(:budget_group, budget: budget) + carabanchel = create(:budget_heading, group: districts) + salamanca = create(:budget_heading, group: districts) + + all_city_investment = create(:budget_investment, heading: heading) + carabanchel_investment = create(:budget_investment, heading: carabanchel) + + create(:vote, votable: all_city_investment, voter: user) + + expect(carabanchel_investment.valid_heading?(user)).to eq(true) + end end end diff --git a/spec/models/signature_sheet_spec.rb b/spec/models/signature_sheet_spec.rb index 473a7b96d..aeed78996 100644 --- a/spec/models/signature_sheet_spec.rb +++ b/spec/models/signature_sheet_spec.rb @@ -46,12 +46,20 @@ describe SignatureSheet do expect(signature_sheet.name).to eq("Citizen proposal #{proposal.id}") end + it "returns name for spending proposal signature sheets" do spending_proposal = create(:spending_proposal) signature_sheet.signable = spending_proposal expect(signature_sheet.name).to eq("Spending proposal #{spending_proposal.id}") end + + it "returns name for budget investment signature sheets" do + budget_investment = create(:budget_investment) + signature_sheet.signable = budget_investment + + expect(signature_sheet.name).to eq("Investment #{budget_investment.id}") + end end describe "#verify_signatures" do diff --git a/spec/models/signature_spec.rb b/spec/models/signature_spec.rb index 8bb090614..207208bbf 100644 --- a/spec/models/signature_spec.rb +++ b/spec/models/signature_spec.rb @@ -46,49 +46,61 @@ describe Signature do end end - describe "#verified?" do - - it "returns true if user exists" do - user = create(:user, :level_two, document_number: "123A") - signature = create(:signature, document_number: user.document_number) - - expect(signature.verified?).to eq(true) - end - - it "returns true if document number in census" do - signature = create(:signature, document_number: "12345678Z") - - expect(signature.verified?).to eq(true) - end - - it "returns false if user does not exist and not in census" do - signature = create(:signature, document_number: "123A") - - expect(signature.verified?).to eq(false) - end - - end - - describe "#assign_vote" do + describe "#verify" do describe "existing user" do - it "assigns vote to user" do + it "assigns vote to user on proposal" do user = create(:user, :level_two, document_number: "123A") signature = create(:signature, document_number: user.document_number) proposal = signature.signable - signature.assign_vote + signature.verify expect(user.voted_for?(proposal)).to be end + it "assigns vote to user on budget investment" do + investment = create(:budget_investment) + signature_sheet = create(:signature_sheet, signable: investment) + user = create(:user, :level_two, document_number: "123A") + signature = create(:signature, document_number: user.document_number, signature_sheet: signature_sheet) + + signature.verify + + expect(user.voted_for?(investment)).to be + end + it "does not assign vote to user multiple times" do user = create(:user, :level_two, document_number: "123A") signature = create(:signature, document_number: user.document_number) - signature.assign_vote - signature.assign_vote + signature.verify + signature.verify + + expect(Vote.count).to eq(1) + end + + it "does not assigns vote to invalid user on budget investment" do + investment = create(:budget_investment) + signature_sheet = create(:signature_sheet, signable: investment) + user = create(:user, document_number: "123A") + signature = create(:signature, document_number: user.document_number, signature_sheet: signature_sheet) + + signature.verify + + expect(user.voted_for?(investment)).to_not be + expect(Vote.count).to eq(0) + end + + it "does not assign vote to user multiple times on budget investment" do + investment = create(:budget_investment) + signature_sheet = create(:signature_sheet, signable: investment) + user = create(:user, :level_two, document_number: "123A") + signature = create(:signature, document_number: user.document_number, signature_sheet: signature_sheet) + + signature.verify + signature.verify expect(Vote.count).to eq(1) end @@ -100,7 +112,22 @@ describe Signature do signature_sheet = create(:signature_sheet, signable: proposal) signature = create(:signature, signature_sheet: signature_sheet, document_number: user.document_number) - signature.assign_vote + signature.verify + + expect(Vote.count).to eq(1) + end + + it "does not assign vote to user if already voted on budget investment" do + investment = create(:budget_investment) + user = create(:user, :level_two, document_number: "123A") + vote = create(:vote, votable: investment, voter: user) + + signature_sheet = create(:signature_sheet, signable: investment) + signature = create(:signature, document_number: user.document_number, signature_sheet: signature_sheet) + + expect(Vote.count).to eq(1) + + signature.verify expect(Vote.count).to eq(1) end @@ -108,7 +135,7 @@ describe Signature do it "marks the vote as coming from a signature" do signature = create(:signature, document_number: "12345678Z") - signature.assign_vote + signature.verify expect(Vote.last.signature).to eq(signature) end @@ -118,23 +145,27 @@ describe Signature do describe "inexistent user" do it "creates a user with that document number" do + create(:geozone, census_code: "01") signature = create(:signature, document_number: "12345678Z") proposal = signature.signable - signature.assign_vote + signature.verify user = User.last expect(user.document_number).to eq("12345678Z") expect(user.created_from_signature).to eq(true) expect(user.verified_at).to be expect(user.erased_at).to be + expect(user.geozone).to be + expect(user.gender).to be + expect(user.date_of_birth).to be end it "assign the vote to newly created user" do signature = create(:signature, document_number: "12345678Z") proposal = signature.signable - signature.assign_vote + signature.verify user = signature.user expect(user.voted_for?(proposal)).to be @@ -143,22 +174,18 @@ describe Signature do it "assigns signature to vote" do signature = create(:signature, document_number: "12345678Z") - signature.assign_vote + signature.verify expect(Vote.last.signature).to eq(signature) end end - end - - describe "#verify" do - describe "document in census" do - it "calls assign_vote" do + it "calls assign_vote_to_user" do signature = create(:signature, document_number: "12345678Z") - expect(signature).to receive(:assign_vote) + expect(signature).to receive(:assign_vote_to_user) signature.verify end @@ -175,10 +202,10 @@ describe Signature do describe "document not in census" do - it "does not call assign_vote" do + it "does not call assign_vote_to_user" do signature = create(:signature, document_number: "123A") - expect(signature).to_not receive(:assign_vote) + expect(signature).to_not receive(:assign_vote_to_user) signature.verify end