Merge branch 'master' into issue#1575-tag-administration

This commit is contained in:
Raimond Garcia
2017-06-29 19:09:54 +02:00
committed by GitHub
192 changed files with 1260 additions and 738 deletions

View File

@@ -1,5 +1,3 @@
PR_TITLE_GOES_HERE
Where Where
===== =====
* **Related Issue:** LINK_OR_#_REF * **Related Issue:** LINK_OR_#_REF
@@ -7,24 +5,24 @@ Where
What What
==== ====
> Whats the objective of this changes ? - Whats the objective of this changes ?
How How
=== ===
> How you implemented/achieved the objective ? - How you implemented/achieved the objective ?
Screenshots Screenshots
=========== ===========
> If changes affect UI just show them drag&dropping images here - If changes affect UI just show them drag&dropping images here
Test Test
==== ====
> Is manual test needed or you just increased/fixed coverage? - Is manual test needed or you just increased/fixed coverage?
Deployment Deployment
========== ==========
> Any details to remember when this feature is deployed? - Any details to remember when this feature is deployed?
Warnings Warnings
======== ========
> Some caveats or important things to notice? - Some caveats or important things to notice?

View File

@@ -22,6 +22,9 @@ Metrics/LineLength:
Layout/IndentationConsistency: Layout/IndentationConsistency:
EnforcedStyle: rails EnforcedStyle: rails
Style/EmptyMethod:
Enabled: false
Style/StringLiterals: Style/StringLiterals:
Enabled: false Enabled: false
@@ -31,6 +34,9 @@ Style/FrozenStringLiteralComment:
Style/PercentLiteralDelimiters: Style/PercentLiteralDelimiters:
Enabled: false Enabled: false
Style/SymbolArray:
Enabled: false
Layout/EmptyLinesAroundClassBody: Layout/EmptyLinesAroundClassBody:
Enabled: false Enabled: false

View File

@@ -86,14 +86,6 @@ Performance/RedundantMatch:
- 'app/controllers/valuation/spending_proposals_controller.rb' - 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/helpers/embed_videos_helper.rb' - 'app/helpers/embed_videos_helper.rb'
# Offense count: 2
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: strict, flexible
Rails/Date:
Exclude:
- 'app/controllers/concerns/commentable_actions.rb'
- 'app/models/direct_message.rb'
# Offense count: 4 # Offense count: 4
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: Whitelist. # Configuration parameters: Whitelist.
@@ -138,35 +130,6 @@ Rails/OutputSafety:
- 'app/helpers/users_helper.rb' - 'app/helpers/users_helper.rb'
- 'app/helpers/valuation_helper.rb' - 'app/helpers/valuation_helper.rb'
# Offense count: 6
# Cop supports --auto-correct.
Rails/PluralizationGrammar:
Exclude:
- 'spec/features/admin/banners_spec.rb'
- 'spec/features/debates_spec.rb'
- 'spec/features/proposals_spec.rb'
- 'spec/models/residence_spec.rb'
# Offense count: 11
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: strict, flexible
Rails/TimeZone:
Exclude:
- 'lib/score_calculator.rb'
- 'spec/controllers/admin/api/stats_controller_spec.rb'
- 'spec/models/ahoy/data_source_spec.rb'
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/Validation:
Exclude:
- 'app/models/comment.rb'
- 'app/models/spending_proposal.rb'
- 'app/models/verification/residence.rb'
- 'app/models/verification/sms.rb'
# Offense count: 9 # Offense count: 9
Style/AccessorMethodName: Style/AccessorMethodName:
Exclude: Exclude:
@@ -202,29 +165,6 @@ Layout/AlignParameters:
- 'spec/models/user_spec.rb' - 'spec/models/user_spec.rb'
- 'spec/rails_helper.rb' - 'spec/rails_helper.rb'
# Offense count: 2
# Cop supports --auto-correct.
Layout/BlockEndNewline:
Exclude:
- 'app/models/banner.rb'
- 'spec/features/users_auth_spec.rb'
# Offense count: 19
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: braces, no_braces, context_dependent
Style/BracesAroundHashParameters:
Exclude:
- 'app/controllers/valuation/spending_proposals_controller.rb'
- 'app/models/concerns/searchable.rb'
- 'app/models/verification/residence.rb'
- 'lib/manager_authenticator.rb'
- 'spec/controllers/management/users_controller_spec.rb'
- 'spec/features/admin/spending_proposals_spec.rb'
- 'spec/lib/manager_authenticator_spec.rb'
- 'spec/models/residence_spec.rb'
- 'spec/models/user_spec.rb'
# Offense count: 57 # Offense count: 57
# Configuration parameters: EnforcedStyle, SupportedStyles. # Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: nested, compact # SupportedStyles: nested, compact
@@ -276,32 +216,6 @@ Style/EmptyCaseCondition:
Exclude: Exclude:
- 'app/models/concerns/verification.rb' - 'app/models/concerns/verification.rb'
# Offense count: 9
# Cop supports --auto-correct.
Layout/EmptyLines:
Exclude:
- 'app/models/concerns/search_cache.rb'
- 'app/models/notification.rb'
- 'spec/features/admin/spending_proposals_spec.rb'
- 'spec/features/admin/verifications_spec.rb'
- 'spec/features/debates_spec.rb'
- 'spec/features/registration_form_spec.rb'
- 'spec/features/users_auth_spec.rb'
- 'spec/features/verification/verified_user_spec.rb'
- 'spec/support/verifiable.rb'
# Offense count: 1
# Cop supports --auto-correct.
Layout/EmptyLinesAroundAccessModifier:
Exclude:
- 'app/controllers/users_controller.rb'
# Offense count: 29
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment.
Layout/ExtraSpacing:
Enabled: false
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
@@ -315,15 +229,6 @@ Layout/FirstParameterIndentation:
Style/GuardClause: Style/GuardClause:
Enabled: false Enabled: false
# Offense count: 10
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
Style/HashSyntax:
Exclude:
- 'lib/sms_api.rb'
- 'spec/factories.rb'
# Offense count: 6 # Offense count: 6
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: MaxLineLength. # Configuration parameters: MaxLineLength.
@@ -607,111 +512,6 @@ Style/RescueModifier:
- 'app/controllers/concerns/commentable_actions.rb' - 'app/controllers/concerns/commentable_actions.rb'
- 'app/controllers/verification/sms_controller.rb' - 'app/controllers/verification/sms_controller.rb'
# Offense count: 2
# Cop supports --auto-correct.
Layout/SpaceAfterColon:
Exclude:
- 'spec/models/user_spec.rb'
# Offense count: 14
# Cop supports --auto-correct.
Layout/SpaceAfterComma:
Exclude:
- 'app/models/ahoy/data_source.rb'
- 'app/models/banner.rb'
- 'app/models/concerns/search_cache.rb'
- 'app/models/concerns/taggable.rb'
- 'app/models/spending_proposal.rb'
- 'app/models/user.rb'
- 'spec/features/valuation/spending_proposals_spec.rb'
- 'spec/lib/census_api_spec.rb'
- 'spec/models/abilities/moderator_spec.rb'
- 'spec/models/verification/management/email_spec.rb'
# Offense count: 1
# Cop supports --auto-correct.
Layout/SpaceAfterNot:
Exclude:
- 'app/models/flag.rb'
# Offense count: 20
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: space, no_space
Layout/SpaceAroundEqualsInParameterDefault:
Exclude:
- 'app/helpers/cache_keys_helper.rb'
- 'app/helpers/proposals_helper.rb'
- 'app/helpers/spending_proposals_helper.rb'
- 'app/helpers/stats_helper.rb'
- 'app/helpers/tracks_helper.rb'
- 'app/helpers/valuation_helper.rb'
- 'app/mailers/devise_mailer.rb'
- 'app/models/comment.rb'
- 'app/models/tag_cloud.rb'
- 'app/models/verification/residence.rb'
- 'lib/acts_as_paranoid_aliases.rb'
- 'lib/capistrano/template.rb'
- 'lib/census_api.rb'
- 'lib/manager_authenticator.rb'
- 'spec/support/common_actions.rb'
# Offense count: 66
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment.
Layout/SpaceAroundOperators:
Enabled: false
# Offense count: 6
# Cop supports --auto-correct.
Layout/SpaceBeforeComma:
Exclude:
- 'app/models/proposal.rb'
- 'spec/controllers/management/sessions_controller_spec.rb'
- 'spec/controllers/management/users_controller_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment.
Layout/SpaceBeforeFirstArg:
Exclude:
- 'spec/factories.rb'
# Offense count: 9
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: require_no_space, require_space
Layout/SpaceInLambdaLiteral:
Exclude:
- 'app/models/concerns/filterable.rb'
- 'app/models/spending_proposal.rb'
- 'app/models/user.rb'
- 'app/models/verified_user.rb'
# Offense count: 8
# Cop supports --auto-correct.
Layout/SpaceInsideParens:
Exclude:
- 'app/models/user.rb'
- 'lib/manager_authenticator.rb'
- 'spec/features/proposals_spec.rb'
- 'spec/models/abilities/moderator_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
Layout/SpaceInsidePercentLiteralDelimiters:
Exclude:
- 'app/models/activity.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiteralsInInterpolation:
Exclude:
- 'app/controllers/stats_controller.rb'
- 'app/models/proposal.rb'
# Offense count: 9 # Offense count: 9
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: IgnoredMethods. # Configuration parameters: IgnoredMethods.
@@ -724,12 +524,6 @@ Style/SymbolProc:
- 'lib/manager_authenticator.rb' - 'lib/manager_authenticator.rb'
- 'spec/factories.rb' - 'spec/factories.rb'
# Offense count: 2
# Cop supports --auto-correct.
Layout/TrailingWhitespace:
Exclude:
- 'app/controllers/admin/api/stats_controller.rb'
# Offense count: 31 # Offense count: 31
# Cop supports --auto-correct. # Cop supports --auto-correct.
Style/UnneededInterpolation: Style/UnneededInterpolation:
@@ -759,6 +553,8 @@ Style/WordArray:
# Offense count: 1 # Offense count: 1
# Cop supports --auto-correct. # Cop supports --auto-correct.
Style/ZeroLengthPredicate: # Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: braces, no_braces, context_dependent
Style/BracesAroundHashParameters:
Exclude: Exclude:
- 'app/models/concerns/verification.rb' - 'app/models/concerns/searchable.rb'

38
CHANGELOG.md Normal file
View File

@@ -0,0 +1,38 @@
### 0.9 - 2017-06-15
* New features
* Budgets
* Basic polls
* Collaborative legistlation
* Custom pages
* GraphQL API
* Improved admin section
* Enhancements
* Improved admin section
* Rails 4.2.8
* Ruby 2.3.2
* Bug fixes
* CKEditor locale compilation fixed
* Fixed bugs in mobile layouts
* Deprecations
* SpendingProposals are deprecated now in favor of Budgets
### 0.8 - 2016-07-21
* New features
* Support for customization schema, vía specific custom files, assets and folders
* Enhancements
* Rails 2.4.7
* Ruby 2.3.1
* Bug fixes
* Fixed bug causing errors on user deletion
### 0.7 - 2016-04-25
* New features
* Debates
* Proposals
* Basic Spending Proposals
* Enhancements
* Rails 2.4.6
* Ruby 2.2.3

View File

@@ -1,15 +1,16 @@
# How to Contribute to this Project # How to Contribute to this Project
## Team members ## Core team members
* Raimond Garcia [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000) * Raimond García [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000)
* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu) * Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu)
* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik) * Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik)
* Alberto Garcia Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza) * Alberto García Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza)
* Alberto Calderón [github](https://github.com/bertocq) | [twitter](https://twitter.com/bertocq)
## Code of conduct ## Code of conduct
The team members and the project's community adopts an inclusive Code of Conduct that you can read in the [CODE_OF_CONDUCT_EN.md](CODE_OF_CONDUCT_EN.md) file. The core team members and the project's community adopts an inclusive Code of Conduct that you can read in the [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) file.
## Report an issue ## Report an issue
@@ -36,6 +37,8 @@ If you want to contribute code to solve an issue:
* Follow these [best practices](https://github.com/styleguide/ruby) * Follow these [best practices](https://github.com/styleguide/ruby)
* Open a *pull request* to the main repository describing what issue you are addressing. * Open a *pull request* to the main repository describing what issue you are addressing.
**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
## Cleaning up ## Cleaning up
In the rush of time sometimes things get messy, you can help us cleaning things up: In the rush of time sometimes things get messy, you can help us cleaning things up:

View File

@@ -2,10 +2,11 @@
## Miembros del equipo ## Miembros del equipo
* Raimond Garcia [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000) * Raimond García [github](https://github.com/voodoorai2000) | [twitter](https://twitter.com/voodoorai2000)
* Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu) * Juanjo Bazán [github](https://github.com/xuanxu) | [twitter](https://twitter.com/xuanxu)
* Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik) * Enrique García Cota [github](https://github.com/kikito) | [twitter](https://twitter.com/otikik)
* Alberto Garcia Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza) * Alberto García Cabeza [github](https://github.com/decabeza) | [twitter](https://twitter.com/decabeza)
* Alberto Calderón [github](https://github.com/bertocq) | [twitter](https://twitter.com/bertocq)
## Código de conducta ## Código de conducta
@@ -34,7 +35,10 @@ Cuando quieras resolver una incidencia mediante código:
* Añade el código necesario para resolver la incidencia en tantos commits como sea preciso * Añade el código necesario para resolver la incidencia en tantos commits como sea preciso
* Asegúrate de que los tests pasan (y escribe más tests para probar la nueva funcionalidad si fuera preciso) * Asegúrate de que los tests pasan (y escribe más tests para probar la nueva funcionalidad si fuera preciso)
* Sigue estas [buenas prácticas](https://github.com/styleguide/ruby) * Sigue estas [buenas prácticas](https://github.com/styleguide/ruby)
* Envía una *pull request* al repositorio principal indicando la incidencia que se está arreglando * Envía una *pull request* al repositorio principal indicando la incidencia que se está arreglando.
**¿Es tu primer Pull Request?** Puedes aprender en este curso gratuito (en inglés) sobre [cómo contribuir a un proyecto OpenSource en GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
## Limpiar ## Limpiar

10
Gemfile
View File

@@ -1,7 +1,7 @@
source 'https://rubygems.org' source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.8' gem 'rails', '4.2.9'
# Use PostgreSQL # Use PostgreSQL
gem 'pg', '~> 0.20.0' gem 'pg', '~> 0.20.0'
# Use SCSS for stylesheets # Use SCSS for stylesheets
@@ -88,10 +88,10 @@ group :development, :test do
gem 'quiet_assets' gem 'quiet_assets'
gem 'letter_opener_web', '~> 1.3.1' gem 'letter_opener_web', '~> 1.3.1'
gem 'i18n-tasks', '~> 0.9.15' gem 'i18n-tasks', '~> 0.9.15'
gem 'capistrano', '~> 3.8.1', require: false gem 'capistrano', '~> 3.8.1', require: false
gem 'capistrano-bundler', '~> 1.2', require: false gem 'capistrano-bundler', '~> 1.2', require: false
gem "capistrano-rails", '~> 1.2.3', require: false gem "capistrano-rails", '~> 1.2.3', require: false
gem 'rvm1-capistrano3', require: false gem 'rvm1-capistrano3', require: false
gem 'capistrano3-delayed-job', '~> 1.7.3' gem 'capistrano3-delayed-job', '~> 1.7.3'
gem "bullet", '~> 5.5.1' gem "bullet", '~> 5.5.1'
gem "faker", '~> 1.7.3' gem "faker", '~> 1.7.3'

View File

@@ -2,36 +2,36 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
remote: https://rails-assets.org/ remote: https://rails-assets.org/
specs: specs:
actionmailer (4.2.8) actionmailer (4.2.9)
actionpack (= 4.2.8) actionpack (= 4.2.9)
actionview (= 4.2.8) actionview (= 4.2.9)
activejob (= 4.2.8) activejob (= 4.2.9)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.8) actionpack (4.2.9)
actionview (= 4.2.8) actionview (= 4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
rack (~> 1.6) rack (~> 1.6)
rack-test (~> 0.6.2) rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.8) actionview (4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.3) rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (4.2.8) activejob (4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
globalid (>= 0.3.0) globalid (>= 0.3.0)
activemodel (4.2.8) activemodel (4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
builder (~> 3.1) builder (~> 3.1)
activerecord (4.2.8) activerecord (4.2.9)
activemodel (= 4.2.8) activemodel (= 4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
arel (~> 6.0) arel (~> 6.0)
activesupport (4.2.8) activesupport (4.2.9)
i18n (~> 0.7) i18n (~> 0.7)
minitest (~> 5.1) minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4) thread_safe (~> 0.3, >= 0.3.4)
@@ -174,8 +174,8 @@ GEM
rspec-core (~> 3.0) rspec-core (~> 3.0)
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
geocoder (1.4.3) geocoder (1.4.3)
globalid (0.3.7) globalid (0.4.0)
activesupport (>= 4.1.0) activesupport (>= 4.2.0)
graphiql-rails (1.4.1) graphiql-rails (1.4.1)
rails rails
graphql (1.6.3) graphql (1.6.3)
@@ -188,7 +188,7 @@ GEM
htmlentities (4.3.4) htmlentities (4.3.4)
httpi (2.4.1) httpi (2.4.1)
rack rack
i18n (0.8.1) i18n (0.8.4)
i18n-tasks (0.9.15) i18n-tasks (0.9.15)
activesupport (>= 4.0.2) activesupport (>= 4.0.2)
ast (>= 2.1.0) ast (>= 2.1.0)
@@ -248,8 +248,8 @@ GEM
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521) mime-types-data (3.2016.0521)
mimemagic (0.3.2) mimemagic (0.3.2)
mini_portile2 (2.1.0) mini_portile2 (2.2.0)
minitest (5.10.1) minitest (5.10.2)
mixlib-cli (1.7.0) mixlib-cli (1.7.0)
mixlib-config (2.2.4) mixlib-config (2.2.4)
multi_json (1.12.1) multi_json (1.12.1)
@@ -259,8 +259,8 @@ GEM
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (4.1.0) net-ssh (4.1.0)
newrelic_rpm (4.1.0.333) newrelic_rpm (4.1.0.333)
nokogiri (1.7.2) nokogiri (1.8.0)
mini_portile2 (~> 2.1.0) mini_portile2 (~> 2.2.0)
nori (2.6.0) nori (2.6.0)
oauth (0.5.1) oauth (0.5.1)
oauth2 (1.3.1) oauth2 (1.3.1)
@@ -313,23 +313,23 @@ GEM
public_suffix (2.0.5) public_suffix (2.0.5)
quiet_assets (1.1.0) quiet_assets (1.1.0)
railties (>= 3.1, < 5.0) railties (>= 3.1, < 5.0)
rack (1.6.5) rack (1.6.8)
rack-accept (0.4.5) rack-accept (0.4.5)
rack (>= 0.4) rack (>= 0.4)
rack-attack (5.0.1) rack-attack (5.0.1)
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (4.2.8) rails (4.2.9)
actionmailer (= 4.2.8) actionmailer (= 4.2.9)
actionpack (= 4.2.8) actionpack (= 4.2.9)
actionview (= 4.2.8) actionview (= 4.2.9)
activejob (= 4.2.8) activejob (= 4.2.9)
activemodel (= 4.2.8) activemodel (= 4.2.9)
activerecord (= 4.2.8) activerecord (= 4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.2.8) railties (= 4.2.9)
sprockets-rails sprockets-rails
rails-assets-markdown-it (8.2.1) rails-assets-markdown-it (8.2.1)
rails-deprecated_sanitizer (1.0.3) rails-deprecated_sanitizer (1.0.3)
@@ -340,9 +340,9 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1) rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (4.2.8) railties (4.2.9)
actionpack (= 4.2.8) actionpack (= 4.2.9)
activesupport (= 4.2.8) activesupport (= 4.2.9)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.2.2) rainbow (2.2.2)
@@ -541,7 +541,7 @@ DEPENDENCIES
pg_search pg_search
poltergeist (~> 1.15.0) poltergeist (~> 1.15.0)
quiet_assets quiet_assets
rails (= 4.2.8) rails (= 4.2.9)
rails-assets-markdown-it! rails-assets-markdown-it!
redcarpet (~> 3.4.0) redcarpet (~> 3.4.0)
responders (~> 2.4.0) responders (~> 2.4.0)

View File

@@ -15,6 +15,7 @@ Citizen Participation and Open Government Application
[![A11y issues checked with Rocket Validator](https://rocketvalidator.com/badges/checked_with_rocket_validator.svg?url=https://rocketvalidator.com)](https://rocketvalidator.com/opensource) [![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) [![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)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/consul/consul/issues?q=is%3Aissue+is%3Aopen+label%3APRs-welcome)
This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website
@@ -51,7 +52,7 @@ Run the app locally:
bin/rails s bin/rails s
``` ```
Prerequisites for testing: install PhantomJS >= 1.9.8 Prerequisites for testing: install PhantomJS >= 2.1.1
Run the tests with: Run the tests with:
@@ -65,6 +66,8 @@ If you add SCSS code you can check it with:
scss-lint scss-lint
``` ```
To maintain accesibility level, if you add new colors use a [Color contrast checker](http://webaim.org/resources/contrastchecker/) (WCAG AA is mandatory, WCAG AAA is recommended)
If you work on Coffeescript code you can check it with [coffeelint](http://www.coffeelint.org/) (install with `npm install -g coffeelint`) : If you work on Coffeescript code you can check it with [coffeelint](http://www.coffeelint.org/) (install with `npm install -g coffeelint`) :
``` ```
@@ -100,4 +103,4 @@ Code published under AFFERO GPL v3 (see [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt)
## Contributions ## Contributions
See [CONTRIBUTING_EN.md](CONTRIBUTING_EN.md) See [CONTRIBUTING.md](CONTRIBUTING.md)

View File

@@ -15,6 +15,7 @@ Aplicación de Participación Ciudadana y Gobierno Abierto
[![A11y issues checked with Rocket Validator](https://rocketvalidator.com/badges/checked_with_rocket_validator.svg?url=https://rocketvalidator.com)](https://rocketvalidator.com/opensource) [![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) [![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)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/consul/consul/issues?q=is%3Aissue+is%3Aopen+label%3APRs-welcome)
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid. Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid.
@@ -51,7 +52,7 @@ Para ejecutar la aplicación en local:
bin/rails s bin/rails s
``` ```
Prerequisitos para los tests: tener instalado PhantomJS >= 1.9.8 Prerequisitos para los tests: tener instalado PhantomJS >= 2.1.1
Para ejecutar los tests: Para ejecutar los tests:
@@ -65,6 +66,8 @@ Si añades código SCSS puedes revisarlo con:
scss-lint scss-lint
``` ```
Para mantener el nivel de accesibilidad, si añades colores nuevos utiliza un [Comprobador de contraste de color](http://webaim.org/resources/contrastchecker/) (WCAG AA es obligatorio, WCAG AAA es recomendable)
Si trabajas en código coffeescript puedes revisarlo con [coffeelint](http://www.coffeelint.org/) (instalalo con `npm install -g coffeelint`) : Si trabajas en código coffeescript puedes revisarlo con [coffeelint](http://www.coffeelint.org/) (instalalo con `npm install -g coffeelint`) :
``` ```

View File

@@ -102,27 +102,47 @@
.annotator-hl { .annotator-hl {
cursor: pointer; cursor: pointer;
background: rgba(255, 255, 10, 0.2); background: rgba(255, 249, 218, 0.75);
}
.annotator-hl.weight-1 { &.weight-1 {
background: #fff9da; background: hsla(50, 100, 93, 0.5);
}
.annotator-hl.weight-2 { .weight-1 {
background: #fff5bc; background: hsla(50, 100, 93, 0.75);
} }
}
.annotator-hl.weight-3 { &.weight-2 {
background: #fff1a2; background: hsla(63, 78, 86, 0.5);
}
.annotator-hl.weight-4 { .weight-2 {
background: #ffef8c; background: hsla(63, 78, 86, 0.75);
} }
}
.annotator-hl.weight-5 { &.weight-3 {
background: #ffe95f; background: hsla(52, 100, 85, 0.5);
.weight-3 {
background: hsla(52, 100, 85, 0.75);
}
}
&.weight-4 {
background: hsla(51, 91, 75, 0.5);
.weight-4 {
background: hsla(51, 91, 75, 0.75);
}
}
&.weight-5 {
background: hsla(46, 83, 60, 0.5);
.weight-5 {
background: hsla(46, 83, 60, 0.5);
}
}
} }
.current-annotation { .current-annotation {

View File

@@ -806,7 +806,7 @@ form {
} }
} }
[type]:not([type=submit]):not([type=file]):not([type=checkbox]):not([type=radio]) { [type]:not([type=submit]):not([type=file]):not([type=checkbox]):not([type=radio]):not(.close-button) {
background: #f8f8f8; background: #f8f8f8;
height: $line-height * 2; height: $line-height * 2;
margin-bottom: rem-calc(16); margin-bottom: rem-calc(16);
@@ -825,23 +825,6 @@ form {
margin: $line-height / 2 0 $line-height / 2 $line-height / 4; margin: $line-height / 2 0 $line-height / 2 $line-height / 4;
} }
.note,
.note-marked {
display: block;
font-size: rem-calc(13);
margin-bottom: $line-height / 2;
}
.note-marked {
background: #ff0;
display: inline-block;
em {
background: #fff;
display: block;
}
}
.ckeditor { .ckeditor {
min-height: $line-height * 13; min-height: $line-height * 13;
} }
@@ -893,7 +876,7 @@ form {
.callout { .callout {
font-size: $small-font-size; font-size: $small-font-size;
a { a:not(.button) {
font-weight: bold; font-weight: bold;
text-decoration: underline; text-decoration: underline;
} }
@@ -945,6 +928,14 @@ form {
} }
} }
.callout {
&.highlight,
&.light {
border: 0;
}
}
// 08. User account // 08. User account
// ---------------- // ----------------

View File

@@ -494,6 +494,109 @@
} }
} }
.tab-milestones ul {
margin-top: rem-calc(40);
position: relative;
li {
margin: 0 auto;
position: relative;
width: 0;
}
li::before {
background: $budget;
border-radius: rem-calc(20);
content: '';
height: rem-calc(20);
position: absolute;
top: 5px;
transform: translateX(-50%);
width: rem-calc(20);
z-index: 2;
}
li::after {
background: $light-gray;
bottom: 100%;
content: '';
height: 100%;
position: absolute;
top: 25px;
width: 1px;
z-index: 1;
}
}
.tab-milestones ul .milestone-content {
padding: $line-height / 6 $line-height / 2;
position: relative;
h3 {
margin-bottom: 0;
}
.milestone-date {
color: $text-medium;
font-size: $small-font-size;
}
}
.tab-milestones .timeline ul li:nth-child(odd),
.tab-milestones .timeline ul li:nth-child(even) {
.milestone-content {
@include breakpoint(medium) {
width: rem-calc(300);
}
@include breakpoint(large) {
width: rem-calc(450);
}
}
}
.tab-milestones .timeline ul li:nth-child(odd) {
.milestone-content {
text-align: right;
@include breakpoint(medium) {
margin-left: rem-calc(-315);
}
@include breakpoint(large) {
margin-left: rem-calc(-465);
}
}
}
.tab-milestones .timeline ul li:nth-child(even) {
.milestone-content {
left: 15px;
}
}
.tab-milestones {
@include breakpoint(small only) {
.timeline ul li {
width: 100%;
&:nth-child(odd),
&:nth-child(even) {
.milestone-content {
left: 15px;
text-align: left;
}
}
}
}
}
// 04. List participation // 04. List participation
// ---------------------- // ----------------------

View File

@@ -12,7 +12,7 @@ class Admin::BudgetHeadingsController < Admin::BaseController
private private
def budget_heading_params def budget_heading_params
params.require(:budget_heading).permit(:name, :price, :geozone_id) params.require(:budget_heading).permit(:name, :price, :population)
end end
end end

View File

@@ -0,0 +1,55 @@
class Admin::BudgetInvestmentMilestonesController < Admin::BaseController
before_action :load_budget_investment, only: [:index, :new, :create, :edit, :update, :destroy]
before_action :load_budget_investment_milestone, only: [:edit, :update, :destroy]
def index
end
def new
@milestone = Budget::Investment::Milestone.new
end
def create
@milestone = Budget::Investment::Milestone.new(milestone_params)
@milestone.investment = @investment
if @milestone.save
redirect_to admin_budget_budget_investment_path(@investment.budget, @investment), notice: t('admin.milestones.create.notice')
else
render :new
end
end
def edit
end
def update
if @milestone.update(milestone_params)
redirect_to admin_budget_budget_investment_path(@investment.budget, @investment), notice: t('admin.milestones.update.notice')
else
render :edit
end
end
def destroy
@milestone.destroy
redirect_to admin_budget_budget_investment_path(@investment.budget, @investment), notice: t('admin.milestones.delete.notice')
end
private
def milestone_params
params.require(:budget_investment_milestone)
.permit(:title, :description, :budget_investment_id)
end
def load_budget_investment
@investment = Budget::Investment.find params[:budget_investment_id]
end
def load_budget_investment_milestone
@milestone = Budget::Investment::Milestone.find params[:id]
end
end

View File

@@ -14,10 +14,15 @@ class Admin::BudgetsController < Admin::BaseController
@budget = Budget.includes(groups: :headings).find(params[:id]) @budget = Budget.includes(groups: :headings).find(params[:id])
end end
def new def new; end
end
def edit def edit; end
def calculate_winners
return unless @budget.balloting_process?
@budget.headings.each { |heading| Budget::Result.new(@budget, heading).calculate_winners }
redirect_to admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'winners'),
notice: I18n.t("admin.budgets.winners.calculated")
end end
def update def update

View File

@@ -60,13 +60,14 @@ class Admin::Poll::PollsController < Admin::BaseController
end end
def search_questions def search_questions
@questions = ::Poll::Question.where("poll_id IS ? OR poll_id != ?", nil, @poll.id).search({search: @search}).order(title: :asc) @questions = ::Poll::Question.where("poll_id IS ? OR poll_id != ?", nil, @poll.id).search(search: @search).order(title: :asc)
respond_to do |format| respond_to do |format|
format.js format.js
end end
end end
private private
def load_geozones def load_geozones
@geozones = Geozone.all.order(:name) @geozones = Geozone.all.order(:name)
end end

View File

@@ -1,7 +1,7 @@
class Admin::SettingsController < Admin::BaseController class Admin::SettingsController < Admin::BaseController
def index def index
all_settings = (Setting.all).group_by { |s| s.type } all_settings = (Setting.all).group_by { |s| s.type }
@settings = all_settings['common'] @settings = all_settings['common']
@feature_flags = all_settings['feature'] @feature_flags = all_settings['feature']
@banner_styles = all_settings['banner-style'] @banner_styles = all_settings['banner-style']

View File

@@ -4,7 +4,7 @@ class Admin::UsersController < Admin::BaseController
def index def index
if params[:search] if params[:search]
s = params[:search] s = params[:search]
@users = User.where("username ILIKE ? OR email ILIKE ? OR document_number ILIKE ?", "%#{s}%","%#{s}%","%#{s}%").page(params[:page]) @users = User.where("username ILIKE ? OR email ILIKE ? OR document_number ILIKE ?", "%#{s}%", "%#{s}%", "%#{s}%").page(params[:page])
else else
@users = @users.page(params[:page]) @users = @users.page(params[:page])
end end

View File

@@ -93,7 +93,7 @@ module Budgets
def set_random_seed def set_random_seed
if params[:order] == 'random' || params[:order].blank? if params[:order] == 'random' || params[:order].blank?
params[:random_seed] ||= rand(99)/100.0 params[:random_seed] ||= rand(99) / 100.0
seed = Float(params[:random_seed]) rescue 0 seed = Float(params[:random_seed]) rescue 0
Budget::Investment.connection.execute("select setseed(#{seed})") Budget::Investment.connection.execute("select setseed(#{seed})")
else else

View File

@@ -36,7 +36,7 @@ class GraphqlController < ApplicationController
def query_string def query_string
if request.headers["CONTENT_TYPE"] == 'application/graphql' if request.headers["CONTENT_TYPE"] == 'application/graphql'
request.body.string # request.body.class => StringIO request.body.string # request.body.class => StringIO
else else
params[:query] params[:query]
end end

View File

@@ -19,13 +19,14 @@ class Legislation::AnswersController < Legislation::BaseController
end end
else else
respond_to do |format| respond_to do |format|
format.js { render json: {} , status: :not_found } format.js { render json: {}, status: :not_found }
format.html { redirect_to legislation_process_question_path(@process, @question), alert: t('legislation.questions.participation.phase_not_open') } format.html { redirect_to legislation_process_question_path(@process, @question), alert: t('legislation.questions.participation.phase_not_open') }
end end
end end
end end
private private
def answer_params def answer_params
params.require(:legislation_answer).permit( params.require(:legislation_answer).permit(
:legislation_question_option_id, :legislation_question_option_id,

View File

@@ -20,7 +20,7 @@ class Management::Budgets::InvestmentsController < Management::BaseController
@investment.author = managed_user @investment.author = managed_user
if @investment.save if @investment.save
notice= t('flash.actions.create.notice', resource_name: Budget::Investment.model_name.human, count: 1) notice = t('flash.actions.create.notice', resource_name: Budget::Investment.model_name.human, count: 1)
redirect_to management_budget_investment_path(@budget, @investment), notice: notice redirect_to management_budget_investment_path(@budget, @investment), notice: notice
else else
render :new render :new

View File

@@ -28,6 +28,7 @@ class Officing::FinalRecountsController < Officing::BaseController
end end
private private
def load_poll def load_poll
@poll = Poll.expired.find(params[:poll_id]) @poll = Poll.expired.find(params[:poll_id])
end end

View File

@@ -27,6 +27,7 @@ class Officing::RecountsController < Officing::BaseController
end end
private private
def load_poll def load_poll
@poll = Poll.find(params[:poll_id]) @poll = Poll.find(params[:poll_id])
end end

View File

@@ -14,10 +14,10 @@ class SandboxController < ApplicationController
def show def show
if params[:template].index('.') # CVE-2014-0130 if params[:template].index('.') # CVE-2014-0130
render :action => "index" render action: "index"
elsif lookup_context.exists?("sandbox/#{params[:template]}") elsif lookup_context.exists?("sandbox/#{params[:template]}")
if params[:template] == "index" if params[:template] == "index"
render :action => "index" render action: "index"
else else
render "sandbox/#{params[:template]}" render "sandbox/#{params[:template]}"
end end
@@ -25,7 +25,7 @@ class SandboxController < ApplicationController
elsif lookup_context.exists?("sandbox/#{params[:template]}/index") elsif lookup_context.exists?("sandbox/#{params[:template]}/index")
render "sandbox/#{params[:template]}/index" render "sandbox/#{params[:template]}/index"
else else
render :action => "index" render action: "index"
end end
end end

View File

@@ -23,6 +23,6 @@ class StatsController < ApplicationController
private private
def daily_cache(key, &block) def daily_cache(key, &block)
Rails.cache.fetch("public_stats/#{Time.current.strftime("%Y-%m-%d")}/#{key}", &block) Rails.cache.fetch("public_stats/#{Time.current.strftime('%Y-%m-%d')}/#{key}", &block)
end end
end end

View File

@@ -30,7 +30,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
identity = Identity.first_or_create_from_oauth(auth) identity = Identity.first_or_create_from_oauth(auth)
@user = current_user || identity.user || User.first_or_initialize_for_oauth(auth) @user = current_user || identity.user || User.first_or_initialize_for_oauth(auth)
if save_user(@user) if save_user
identity.update(user: @user) identity.update(user: @user)
sign_in_and_redirect @user, event: :authentication sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format? set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
@@ -40,7 +40,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
end end
end end
def save_user(user) def save_user
@user.save || @user.save_requiring_finish_signup @user.save || @user.save_requiring_finish_signup
end end

View File

@@ -10,6 +10,7 @@ class UsersController < ApplicationController
end end
private private
def set_activity_counts def set_activity_counts
@activity_counts = HashWithIndifferentAccess.new( @activity_counts = HashWithIndifferentAccess.new(
proposals: Proposal.where(author_id: @user.id).count, proposals: Proposal.where(author_id: @user.id).count,
@@ -24,7 +25,7 @@ class UsersController < ApplicationController
when "proposals" then load_proposals when "proposals" then load_proposals
when "debates" then load_debates when "debates" then load_debates
when "budget_investments" then load_budget_investments when "budget_investments" then load_budget_investments
when "comments" then load_comments when "comments" then load_comments
else load_available_activity else load_available_activity
end end
end end

View File

@@ -58,7 +58,7 @@ class Valuation::SpendingProposalsController < Valuation::BaseController
end end
def params_for_current_valuator def params_for_current_valuator
params.merge({valuator_id: current_user.valuator.id}) params.merge(valuator_id: current_user.valuator.id)
end end
def restrict_access_to_assigned_items def restrict_access_to_assigned_items

View File

@@ -1,7 +1,7 @@
module BallotsHelper module BallotsHelper
def progress_bar_width(amount_available, amount_spent) def progress_bar_width(amount_available, amount_spent)
(amount_spent/amount_available.to_f * 100).to_s + "%" (amount_spent / amount_available.to_f * 100).to_s + "%"
end end
end end

View File

@@ -1,11 +1,11 @@
module CacheKeysHelper module CacheKeysHelper
def locale_and_user_status(authorable=nil) def locale_and_user_status(authorable = nil)
@cache_key_user ||= calculate_user_status(authorable) @cache_key_user ||= calculate_user_status(authorable)
"#{I18n.locale}/#{@cache_key_user}" "#{I18n.locale}/#{@cache_key_user}"
end end
def calculate_user_status(authorable=nil) def calculate_user_status(authorable = nil)
user_status = "user" user_status = "user"
if user_signed_in? if user_signed_in?

View File

@@ -11,7 +11,7 @@ module EmbedVideosHelper
if server == "Vimeo" if server == "Vimeo"
reg_exp = /vimeo.*(staffpicks\/|channels\/|videos\/|video\/|\/)([^#\&\?]*).*/ reg_exp = /vimeo.*(staffpicks\/|channels\/|videos\/|video\/|\/)([^#\&\?]*).*/
src = "https://player.vimeo.com/video/" src = "https://player.vimeo.com/video/"
elsif server == "YouTube" elsif server == "YouTube"
reg_exp = /youtu.*(be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/ reg_exp = /youtu.*(be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/
src = "https://www.youtube.com/embed/" src = "https://www.youtube.com/embed/"

View File

@@ -13,7 +13,7 @@ module OfficingHelper
officer_assignments.each do |oa| officer_assignments.each do |oa|
options << [oa.booth_assignment.booth.name.to_s, oa.id] options << [oa.booth_assignment.booth.name.to_s, oa.id]
end end
options.sort! {|x, y| x[0]<=>y[0]} options.sort! {|x, y| x[0] <=> y[0]}
options_for_select(options, params[:oa]) options_for_select(options, params[:oa])
end end

View File

@@ -9,7 +9,7 @@ module PollRecountsHelper
end end
def booth_assignment_sum_final_recounts(ba) def booth_assignment_sum_final_recounts(ba)
ba.final_recounts.any? ? ba.final_recounts.to_a.sum(&:count) :nil ba.final_recounts.any? ? ba.final_recounts.to_a.sum(&:count) : nil
end end
end end

View File

@@ -18,7 +18,7 @@ module ProposalsHelper
end end
end end
def namespaced_proposal_path(proposal, options={}) def namespaced_proposal_path(proposal, options = {})
@namespace_proposal_path ||= namespace @namespace_proposal_path ||= namespace
case @namespace_proposal_path case @namespace_proposal_path
when "management" when "management"

View File

@@ -4,7 +4,7 @@ module SpendingProposalsHelper
ActsAsTaggableOn::Tag.spending_proposal_tags.pluck(:name) ActsAsTaggableOn::Tag.spending_proposal_tags.pluck(:name)
end end
def namespaced_spending_proposal_path(spending_proposal, options={}) def namespaced_spending_proposal_path(spending_proposal, options = {})
@namespace_spending_proposal_path ||= namespace @namespace_spending_proposal_path ||= namespace
case @namespace_spending_proposal_path case @namespace_spending_proposal_path
when "management" when "management"

View File

@@ -1,27 +1,27 @@
module StatsHelper module StatsHelper
def events_chart_tag(events, opt={}) def events_chart_tag(events, opt = {})
events = events.join(',') if events.is_a? Array events = events.join(',') if events.is_a? Array
opt[:data] ||= {} opt[:data] ||= {}
opt[:data][:graph] = admin_api_stats_path(events: events) opt[:data][:graph] = admin_api_stats_path(events: events)
content_tag :div, "", opt content_tag :div, "", opt
end end
def visits_chart_tag(opt={}) def visits_chart_tag(opt = {})
events = events.join(',') if events.is_a? Array events = events.join(',') if events.is_a? Array
opt[:data] ||= {} opt[:data] ||= {}
opt[:data][:graph] = admin_api_stats_path(visits: true) opt[:data][:graph] = admin_api_stats_path(visits: true)
content_tag :div, "", opt content_tag :div, "", opt
end end
def spending_proposals_chart_tag(opt={}) def spending_proposals_chart_tag(opt = {})
events = events.join(',') if events.is_a? Array events = events.join(',') if events.is_a? Array
opt[:data] ||= {} opt[:data] ||= {}
opt[:data][:graph] = admin_api_stats_path(spending_proposals: true) opt[:data][:graph] = admin_api_stats_path(spending_proposals: true)
content_tag :div, "", opt content_tag :div, "", opt
end end
def budget_investments_chart_tag(opt={}) def budget_investments_chart_tag(opt = {})
events = events.join(',') if events.is_a? Array events = events.join(',') if events.is_a? Array
opt[:data] ||= {} opt[:data] ||= {}
opt[:data][:graph] = admin_api_stats_path(budget_investments: true) opt[:data][:graph] = admin_api_stats_path(budget_investments: true)

View File

@@ -1,6 +1,6 @@
module TracksHelper module TracksHelper
def track_event(data={}) def track_event(data = {})
track_data = "" track_data = ""
prefix = " data-track-event-" prefix = " data-track-event-"
data.each do |key, value| data.each do |key, value|

View File

@@ -1,6 +1,6 @@
module ValuationHelper module ValuationHelper
def valuator_select_options(valuator=nil) def valuator_select_options(valuator = nil)
if valuator.present? if valuator.present?
Valuator.where.not(id: valuator.id).order("description ASC").order("users.email ASC").includes(:user).collect { |v| [ v.description_or_email, v.id ] }.prepend([valuator.description_or_email, valuator.id]) Valuator.where.not(id: valuator.id).order("description ASC").order("users.email ASC").includes(:user).collect { |v| [ v.description_or_email, v.id ] }.prepend([valuator.description_or_email, valuator.id])
else else

View File

@@ -18,7 +18,7 @@ module VerificationHelper
data_to_mask = match[2] data_to_mask = match[2]
email_provider = match[3] email_provider = match[3]
data_to_display + "*"*data_to_mask.size + "@" + email_provider data_to_display + "*" * data_to_mask.size + "@" + email_provider
end end
end end

View File

@@ -5,7 +5,7 @@ class DeviseMailer < Devise::Mailer
protected protected
def devise_mail(record, action, opts={}) def devise_mail(record, action, opts = {})
I18n.with_locale record.locale do I18n.with_locale record.locale do
super(record, action, opts) super(record, action, opts)
end end

View File

@@ -44,7 +44,7 @@ module Abilities
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
can [:index, :read, :new, :create, :update, :destroy], Budget can [:index, :read, :new, :create, :update, :destroy, :calculate_winners], Budget
can [:read, :create, :update, :destroy], Budget::Group can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :update, :toggle_selection], Budget::Investment can [:hide, :update, :toggle_selection], Budget::Investment

View File

@@ -48,7 +48,7 @@ module Abilities
can :create, Budget::Investment, budget: { phase: "accepting" } can :create, Budget::Investment, budget: { phase: "accepting" }
can :suggest, Budget::Investment, budget: { phase: "accepting" } can :suggest, Budget::Investment, budget: { phase: "accepting" }
can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id
can :vote, Budget::Investment, budget: { phase: "selecting" } can :vote, Budget::Investment, budget: { phase: "selecting" }
can [:show, :create], Budget::Ballot, budget: { phase: "balloting" } can [:show, :create], Budget::Ballot, budget: { phase: "balloting" }
can [:create, :destroy], Budget::Ballot::Line, budget: { phase: "balloting" } can [:create, :destroy], Budget::Ballot::Line, budget: { phase: "balloting" }

View File

@@ -1,8 +1,8 @@
class Activity < ActiveRecord::Base class Activity < ActiveRecord::Base
belongs_to :actionable, -> { with_hidden }, polymorphic: true belongs_to :actionable, -> { with_hidden }, polymorphic: true
belongs_to :user, -> { with_hidden } belongs_to :user, -> { with_hidden }
VALID_ACTIONS = %w( hide block restore valuate ) VALID_ACTIONS = %w(hide block restore valuate)
validates :action, inclusion: {in: VALID_ACTIONS} validates :action, inclusion: {in: VALID_ACTIONS}

View File

@@ -10,7 +10,7 @@ module Ahoy
# chart # chart
def add(name, collection) def add(name, collection)
collections.push data: collection, name: name collections.push data: collection, name: name
collection.each{ |k,v| add_key k } collection.each{ |k, v| add_key k }
end end
def build def build

View File

@@ -5,16 +5,15 @@ class Banner < ActiveRecord::Base
validates :title, presence: true, validates :title, presence: true,
length: { minimum: 2 } length: { minimum: 2 }
validates :description, presence: true validates :description, presence: true
validates :target_url, presence: true validates :target_url, presence: true
validates :style, presence: true validates :style, presence: true
validates :image, presence: true validates :image, presence: true
validates :post_started_at, presence: true validates :post_started_at, presence: true
validates :post_ended_at, presence: true validates :post_ended_at, presence: true
scope :with_active, -> {where("post_started_at <= ?", Time.current). scope :with_active, -> { where("post_started_at <= ?", Time.current).where("post_ended_at >= ?", Time.current) }
where("post_ended_at >= ?", Time.current) }
scope :with_inactive,-> {where("post_started_at > ? or post_ended_at < ?", Time.current, Time.current) } scope :with_inactive, -> { where("post_started_at > ? or post_ended_at < ?", Time.current, Time.current) }
end end

View File

@@ -67,8 +67,12 @@ class Budget < ActiveRecord::Base
phase == "finished" phase == "finished"
end end
def balloting_process?
balloting? || reviewing_ballots?
end
def balloting_or_later? def balloting_or_later?
balloting? || reviewing_ballots? || finished? balloting_process? || finished?
end end
def on_hold? def on_hold?

View File

@@ -20,13 +20,14 @@ class Budget
has_many :valuator_assignments, dependent: :destroy has_many :valuator_assignments, dependent: :destroy
has_many :valuators, through: :valuator_assignments has_many :valuators, through: :valuator_assignments
has_many :comments, as: :commentable has_many :comments, as: :commentable
has_many :milestones
validates :title, presence: true validates :title, presence: true
validates :author, presence: true validates :author, presence: true
validates :description, presence: true validates :description, presence: true
validates :heading_id, presence: true validates :heading_id, presence: true
validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required? validates :unfeasibility_explanation, presence: { if: :unfeasibility_explanation_required? }
validates_presence_of :price, if: :price_required? validates :price, presence: { if: :price_required? }
validates :title, length: { in: 4..Budget::Investment.title_max_length } validates :title, length: { in: 4..Budget::Investment.title_max_length }
validates :description, length: { maximum: Budget::Investment.description_max_length } validates :description, length: { maximum: Budget::Investment.description_max_length }
@@ -59,7 +60,7 @@ class Budget
scope :by_tag, ->(tag_name) { tagged_with(tag_name) } scope :by_tag, ->(tag_name) { tagged_with(tag_name) }
scope :by_valuator, ->(valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) } scope :by_valuator, ->(valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) }
scope :for_render, -> { includes(:heading) } scope :for_render, -> { includes(:heading) }
before_save :calculate_confidence_score before_save :calculate_confidence_score
before_validation :set_responsible_name before_validation :set_responsible_name
@@ -204,8 +205,8 @@ class Budget
end end
def should_show_aside? def should_show_aside?
(budget.selecting? && !unfeasible?) || (budget.selecting? && !unfeasible?) ||
(budget.balloting? && feasible?) || (budget.balloting? && feasible?) ||
(budget.valuating? && !unfeasible?) (budget.valuating? && !unfeasible?)
end end

View File

@@ -0,0 +1,14 @@
class Budget
class Investment
class Milestone < ActiveRecord::Base
belongs_to :investment
validates :title, presence: true
validates :investment, presence: true
def self.title_max_length
80
end
end
end
end

View File

@@ -12,11 +12,10 @@ class Budget
reset_winners reset_winners
investments.each do |investment| investments.each do |investment|
@current_investment = investment @current_investment = investment
if inside_budget? set_winner if inside_budget?
set_winner
end
end end
end end
handle_asynchronously :calculate_winners
def investments def investments
heading.investments.selected.sort_by_ballots heading.investments.selected.sort_by_ballots

View File

@@ -13,7 +13,7 @@ class Comment < ActiveRecord::Base
validates :body, presence: true validates :body, presence: true
validates :user, presence: true validates :user, presence: true
validates_inclusion_of :commentable_type, in: ["Debate", "Proposal", "Budget::Investment", "Poll::Question", "Legislation::Question", "Legislation::Annotation"] validates :commentable_type, inclusion: { in: ["Debate", "Proposal", "Budget::Investment", "Poll::Question", "Legislation::Question", "Legislation::Annotation"] }
validate :validate_body_length validate :validate_body_length
@@ -44,7 +44,7 @@ class Comment < ActiveRecord::Base
after_create :call_after_commented after_create :call_after_commented
def self.build(commentable, user, body, p_id=nil) def self.build(commentable, user, body, p_id = nil)
new commentable: commentable, new commentable: commentable,
user_id: user.id, user_id: user.id,
body: body, body: body,
@@ -64,7 +64,7 @@ class Comment < ActiveRecord::Base
end end
def author=(author) def author=(author)
self.user= author self.user = author
end end
def total_votes def total_votes

View File

@@ -3,7 +3,7 @@ module Conflictable
def conflictive? def conflictive?
return false unless flags_count > 0 && cached_votes_up > 0 return false unless flags_count > 0 && cached_votes_up > 0
cached_votes_up/flags_count.to_f < 5 cached_votes_up / flags_count.to_f < 5
end end
end end

View File

@@ -2,8 +2,8 @@ module Filterable
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
scope :by_official_level, -> (official_level) { where(users: { official_level: official_level }).joins(:author) } scope :by_official_level, ->(official_level) { where(users: { official_level: official_level }).joins(:author) }
scope :by_date_range, -> (date_range) { where(created_at: date_range) } scope :by_date_range, ->(date_range) { where(created_at: date_range) }
end end
class_methods do class_methods do

View File

@@ -14,7 +14,7 @@ module SearchCache
def searchable_values_sql def searchable_values_sql
searchable_values searchable_values
.select{ |k,_| k.present? } .select{ |k, _| k.present? }
.collect{ |value, weight| set_tsvector(value, weight) } .collect{ |value, weight| set_tsvector(value, weight) }
.join(" || ") .join(" || ")
end end
@@ -31,5 +31,4 @@ module SearchCache
ActionController::Base.helpers.sanitize(value, tags: []) ActionController::Base.helpers.sanitize(value, tags: [])
end end
end end

View File

@@ -9,7 +9,7 @@ module Taggable
def tag_list_with_limit(limit = nil) def tag_list_with_limit(limit = nil)
return tags if limit.blank? return tags if limit.blank?
tags.sort{|a,b| b.taggings_count <=> a.taggings_count}[0, limit] tags.sort{|a, b| b.taggings_count <=> a.taggings_count}[0, limit]
end end
def tags_count_out_of_limit(limit = nil) def tags_count_out_of_limit(limit = nil)

View File

@@ -7,7 +7,7 @@ module Verification
scope :level_two_verified, -> { where("users.level_two_verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL) AND verified_at IS NULL") } scope :level_two_verified, -> { where("users.level_two_verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL) AND verified_at IS NULL") }
scope :level_two_or_three_verified, -> { where("users.verified_at IS NOT NULL OR users.level_two_verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL)") } scope :level_two_or_three_verified, -> { where("users.verified_at IS NOT NULL OR users.level_two_verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL)") }
scope :unverified, -> { where("users.verified_at IS NULL AND (users.level_two_verified_at IS NULL AND (users.residence_verified_at IS NULL OR users.confirmed_phone IS NULL))") } scope :unverified, -> { where("users.verified_at IS NULL AND (users.level_two_verified_at IS NULL AND (users.residence_verified_at IS NULL OR users.confirmed_phone IS NULL))") }
scope :incomplete_verification, -> { where("(users.residence_verified_at IS NULL AND users.failed_census_calls_count > ?) OR (users.residence_verified_at IS NOT NULL AND (users.unconfirmed_phone IS NULL OR users.confirmed_phone IS NULL))", 0) } scope :incomplete_verification, -> { where("(users.residence_verified_at IS NULL AND users.failed_census_calls_count > ?) OR (users.residence_verified_at IS NOT NULL AND (users.unconfirmed_phone IS NULL OR users.confirmed_phone IS NULL))", 0) }
end end
def verification_email_sent? def verification_email_sent?
@@ -47,7 +47,7 @@ module Verification
end end
def failed_residence_verification? def failed_residence_verification?
!residence_verified? && failed_census_calls.size > 0 !residence_verified? && !failed_census_calls.empty?
end end
def no_phone_available? def no_phone_available?

View File

@@ -23,7 +23,7 @@ class Flag < ActiveRecord::Base
def self.flagged?(user, flaggable) def self.flagged?(user, flaggable)
return false unless user return false unless user
!! by_user_and_flaggable(user, flaggable).try(:first) !!by_user_and_flaggable(user, flaggable).try(:first)
end end
end end

View File

@@ -35,7 +35,7 @@ class Legislation::Annotation < ActiveRecord::Base
selector_end = "/html/body/#{range_end}" selector_end = "/html/body/#{range_end}"
el_end = doc.at_xpath(selector_end) el_end = doc.at_xpath(selector_end)
remainder_el_start = el_start.text[0 .. range_start_offset-1] unless range_start_offset.zero? remainder_el_start = el_start.text[0 .. range_start_offset - 1] unless range_start_offset.zero?
remainder_el_end = el_end.text[range_end_offset .. -1] remainder_el_end = el_end.text[range_end_offset .. -1]
self.context = "#{remainder_el_start}<span class=annotator-hl>#{quote}</span>#{remainder_el_end}" self.context = "#{remainder_el_start}<span class=annotator-hl>#{quote}</span>#{remainder_el_end}"

View File

@@ -9,7 +9,7 @@ class Legislation::Question < ActiveRecord::Base
has_many :answers, class_name: 'Legislation::Answer', foreign_key: 'legislation_question_id', dependent: :destroy, inverse_of: :question has_many :answers, class_name: 'Legislation::Answer', foreign_key: 'legislation_question_id', dependent: :destroy, inverse_of: :question
has_many :comments, as: :commentable, dependent: :destroy has_many :comments, as: :commentable, dependent: :destroy
accepts_nested_attributes_for :question_options, :reject_if => proc { |attributes| attributes[:value].blank? }, allow_destroy: true accepts_nested_attributes_for :question_options, reject_if: proc { |attributes| attributes[:value].blank? }, allow_destroy: true
validates :process, presence: true validates :process, presence: true
validates :title, presence: true validates :title, presence: true

View File

@@ -7,7 +7,6 @@ class Notification < ActiveRecord::Base
scope :not_emailed, -> { where(emailed_at: nil) } scope :not_emailed, -> { where(emailed_at: nil) }
scope :for_render, -> { includes(:notifiable) } scope :for_render, -> { includes(:notifiable) }
def timestamp def timestamp
notifiable.created_at notifiable.created_at
end end

View File

@@ -6,14 +6,14 @@ class Officing::Residence
before_validation :call_census_api before_validation :call_census_api
validates_presence_of :document_number validates :document_number, presence: true
validates_presence_of :document_type validates :document_type, presence: true
validates_presence_of :year_of_birth validates :year_of_birth, presence: true
validate :allowed_age validate :allowed_age
validate :residence_in_madrid validate :residence_in_madrid
def initialize(attrs={}) def initialize(attrs = {})
super super
clean_document_number clean_document_number
end end
@@ -43,14 +43,13 @@ class Officing::Residence
end end
def store_failed_census_call def store_failed_census_call
FailedCensusCall.create({ FailedCensusCall.create(
user: user, user: user,
document_number: document_number, document_number: document_number,
document_type: document_type, document_type: document_type,
year_of_birth: year_of_birth, year_of_birth: year_of_birth,
poll_officer: officer poll_officer: officer
}) )
end end
def user_exists? def user_exists?

View File

@@ -18,7 +18,7 @@ class Poll < ActiveRecord::Base
scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.current, Time.current) } scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.current, Time.current) }
scope :incoming, -> { where('? < starts_at', Time.current) } scope :incoming, -> { where('? < starts_at', Time.current) }
scope :expired, -> { where('ends_at < ?', Time.current) } scope :expired, -> { where('ends_at < ?', Time.current) }
scope :published, -> { where('published = ?', true) } scope :published, -> { where('published = ?', true) }
scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) }
scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) } scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) }

View File

@@ -2,7 +2,7 @@ class Poll::NullResult < ActiveRecord::Base
VALID_ORIGINS = %w{web booth} VALID_ORIGINS = %w{web booth}
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :booth_assignment belongs_to :booth_assignment
belongs_to :officer_assignment belongs_to :officer_assignment

View File

@@ -19,7 +19,7 @@ class Poll::Question < ActiveRecord::Base
validates :title, length: { minimum: 4 } validates :title, length: { minimum: 4 }
validates :description, length: { maximum: Poll::Question.description_max_length } validates :description, length: { maximum: Poll::Question.description_max_length }
scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) } scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) }
scope :sort_for_list, -> { order('poll_questions.proposal_id IS NULL', :created_at)} scope :sort_for_list, -> { order('poll_questions.proposal_id IS NULL', :created_at)}
scope :for_render, -> { includes(:author, :proposal) } scope :for_render, -> { includes(:author, :proposal) }

View File

@@ -2,7 +2,7 @@ class Poll::WhiteResult < ActiveRecord::Base
VALID_ORIGINS = %w{web booth} VALID_ORIGINS = %w{web booth}
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :booth_assignment belongs_to :booth_assignment
belongs_to :officer_assignment belongs_to :officer_assignment

View File

@@ -38,8 +38,8 @@ class Proposal < ActiveRecord::Base
before_save :calculate_hot_score, :calculate_confidence_score before_save :calculate_hot_score, :calculate_confidence_score
scope :for_render, -> { includes(:tags) } scope :for_render, -> { includes(:tags) }
scope :sort_by_hot_score , -> { reorder(hot_score: :desc) } scope :sort_by_hot_score, -> { reorder(hot_score: :desc) }
scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc) } scope :sort_by_confidence_score, -> { reorder(confidence_score: :desc) }
scope :sort_by_created_at, -> { reorder(created_at: :desc) } scope :sort_by_created_at, -> { reorder(created_at: :desc) }
scope :sort_by_most_commented, -> { reorder(comments_count: :desc) } scope :sort_by_most_commented, -> { reorder(comments_count: :desc) }
@@ -128,7 +128,7 @@ class Proposal < ActiveRecord::Base
end end
def code def code
"#{Setting["proposal_code_prefix"]}-#{created_at.strftime('%Y-%m')}-#{id}" "#{Setting['proposal_code_prefix']}-#{created_at.strftime('%Y-%m')}-#{id}"
end end
def after_commented def after_commented

View File

@@ -2,8 +2,8 @@ class Setting < ActiveRecord::Base
validates :key, presence: true, uniqueness: true validates :key, presence: true, uniqueness: true
default_scope { order(id: :asc) } default_scope { order(id: :asc) }
scope :banner_style, -> { where("key ilike ?", "banner-style.%")} scope :banner_style, -> { where("key ilike ?", "banner-style.%")}
scope :banner_img, -> { where("key ilike ?", "banner-img.%")} scope :banner_img, -> { where("key ilike ?", "banner-img.%")}
def type def type
if feature_flag? if feature_flag?

View File

@@ -15,7 +15,7 @@ class SpendingProposal < ActiveRecord::Base
validates :title, presence: true validates :title, presence: true
validates :author, presence: true validates :author, presence: true
validates :description, presence: true validates :description, presence: true
validates_presence_of :feasible_explanation, if: :feasible_explanation_required? validates :feasible_explanation, presence: { if: :feasible_explanation_required? }
validates :title, length: { in: 4..SpendingProposal.title_max_length } validates :title, length: { in: 4..SpendingProposal.title_max_length }
validates :description, length: { maximum: SpendingProposal.description_max_length } validates :description, length: { maximum: SpendingProposal.description_max_length }
@@ -31,11 +31,11 @@ class SpendingProposal < ActiveRecord::Base
scope :not_unfeasible, -> { where("feasible IS ? OR feasible = ?", nil, true) } scope :not_unfeasible, -> { where("feasible IS ? OR feasible = ?", nil, true) }
scope :with_supports, -> { where('cached_votes_up > 0') } scope :with_supports, -> { where('cached_votes_up > 0') }
scope :by_admin, -> (admin) { where(administrator_id: admin.presence) } scope :by_admin, ->(admin) { where(administrator_id: admin.presence) }
scope :by_tag, -> (tag_name) { tagged_with(tag_name) } scope :by_tag, ->(tag_name) { tagged_with(tag_name) }
scope :by_valuator, -> (valuator) { where("valuation_assignments.valuator_id = ?", valuator.presence).joins(:valuation_assignments) } scope :by_valuator, ->(valuator) { where("valuation_assignments.valuator_id = ?", valuator.presence).joins(:valuation_assignments) }
scope :for_render, -> { includes(:geozone) } scope :for_render, -> { includes(:geozone) }
before_validation :set_responsible_name before_validation :set_responsible_name
@@ -44,7 +44,7 @@ class SpendingProposal < ActiveRecord::Base
end end
def self.filter_params(params) def self.filter_params(params)
params.select{|x,_| %w{geozone_id administrator_id tag_name valuator_id}.include? x.to_s } params.select{|x, _| %w{geozone_id administrator_id tag_name valuator_id}.include? x.to_s }
end end
def self.scoped_filter(params, current_filter) def self.scoped_filter(params, current_filter)

View File

@@ -2,7 +2,7 @@ class TagCloud
attr_accessor :resource_model, :scope attr_accessor :resource_model, :scope
def initialize(resource_model, scope=nil) def initialize(resource_model, scope = nil)
@resource_model = resource_model @resource_model = resource_model
@scope = scope @scope = scope
end end

View File

@@ -56,7 +56,7 @@ class User < ActiveRecord::Base
scope :officials, -> { where("official_level > 0") } scope :officials, -> { where("official_level > 0") }
scope :newsletter, -> { where(newsletter: true) } scope :newsletter, -> { where(newsletter: true) }
scope :for_render, -> { includes(:organization) } scope :for_render, -> { includes(:organization) }
scope :by_document, -> (document_type, document_number) { where(document_type: document_type, document_number: document_number) } scope :by_document, ->(document_type, document_number) { where(document_type: document_type, document_number: document_number) }
scope :email_digest, -> { where(email_digest: true) } scope :email_digest, -> { where(email_digest: true) }
scope :active, -> { where(erased_at: nil) } scope :active, -> { where(erased_at: nil) }
scope :erased, -> { where.not(erased_at: nil) } scope :erased, -> { where.not(erased_at: nil) }
@@ -74,7 +74,7 @@ class User < ActiveRecord::Base
username: auth.info.name || auth.uid, username: auth.info.name || auth.uid,
email: oauth_email, email: oauth_email,
oauth_email: oauth_email, oauth_email: oauth_email,
password: Devise.friendly_token[0,20], password: Devise.friendly_token[0, 20],
terms_of_service: '1', terms_of_service: '1',
confirmed_at: oauth_email_confirmed ? DateTime.current : nil confirmed_at: oauth_email_confirmed ? DateTime.current : nil
) )
@@ -156,7 +156,7 @@ class User < ActiveRecord::Base
def has_official_email? def has_official_email?
domain = Setting['email_domain_for_officials'] domain = Setting['email_domain_for_officials']
email.present? && ( (email.end_with? "@#{domain}") || (email.end_with? ".#{domain}") ) email.present? && ((email.end_with? "@#{domain}") || (email.end_with? ".#{domain}"))
end end
def display_official_position_badge? def display_official_position_badge?

View File

@@ -7,17 +7,17 @@ class Verification::Residence
before_validation :call_census_api before_validation :call_census_api
validates_presence_of :document_number validates :document_number, presence: true
validates_presence_of :document_type validates :document_type, presence: true
validates_presence_of :date_of_birth validates :date_of_birth, presence: true
validates_presence_of :postal_code validates :postal_code, presence: true
validates :terms_of_service, acceptance: { allow_nil: false } validates :terms_of_service, acceptance: { allow_nil: false }
validates :postal_code, length: { is: 5 } validates :postal_code, length: { is: 5 }
validate :allowed_age validate :allowed_age
validate :document_number_uniqueness validate :document_number_uniqueness
def initialize(attrs={}) def initialize(attrs = {})
self.date_of_birth = parse_date('date_of_birth', attrs) self.date_of_birth = parse_date('date_of_birth', attrs)
attrs = remove_date('date_of_birth', attrs) attrs = remove_date('date_of_birth', attrs)
super super
@@ -47,13 +47,13 @@ class Verification::Residence
end end
def store_failed_attempt def store_failed_attempt
FailedCensusCall.create({ FailedCensusCall.create(
user: user, user: user,
document_number: document_number, document_number: document_number,
document_type: document_type, document_type: document_type,
date_of_birth: date_of_birth, date_of_birth: date_of_birth,
postal_code: postal_code postal_code: postal_code
}) )
end end
def geozone def geozone

View File

@@ -3,7 +3,7 @@ class Verification::Sms
attr_accessor :user, :phone, :confirmation_code attr_accessor :user, :phone, :confirmation_code
validates_presence_of :phone validates :phone, presence: true
validates :phone, format: { with: /\A[\d \+]+\z/ } validates :phone, format: { with: /\A[\d \+]+\z/ }
validate :uniqness_phone validate :uniqness_phone

View File

@@ -1,8 +1,8 @@
class VerifiedUser < ActiveRecord::Base class VerifiedUser < ActiveRecord::Base
scope :by_user, -> (user) { where(document_number: user.document_number) } scope :by_user, ->(user) { where(document_number: user.document_number) }
scope :by_email, -> (email) { where(email: email) } scope :by_email, ->(email) { where(email: email) }
scope :by_phone, -> (phone) { where(phone: phone) } scope :by_phone, ->(phone) { where(phone: phone) }
def self.phone?(user) def self.phone?(user)
by_user(user).by_phone(user.unconfirmed_phone).first.present? by_user(user).by_phone(user.unconfirmed_phone).first.present?

View File

@@ -0,0 +1,7 @@
<%= form_for [:admin, @investment.budget, @investment, @milestone] do |f| %>
<%= f.text_field :title, maxlength: Budget::Investment::Milestone.title_max_length %>
<%= f.text_area :description, rows: 5 %>
<%= f.submit nil, class: "button success" %>
<% end %>

View File

@@ -0,0 +1,5 @@
<%= back_link_to admin_budget_budget_investment_path(@investment.budget, @investment) %>
<h2><%= t("admin.milestones.edit.title") %></h2>
<%= render '/admin/budget_investment_milestones/form' %>

View File

@@ -0,0 +1,10 @@
<div class="milestone-new row">
<div class="small-12 column">
<%= back_link_to admin_budget_budget_investment_path(@investment.budget, @investment) %>
<h1><%= t("admin.milestones.new.creating") %></h1>
<%= render "form" %>
</div>
</div>

View File

@@ -0,0 +1,36 @@
<% if @investment.milestones.any? %>
<table>
<thead>
<tr>
<th><%= t("admin.milestones.index.table_id") %></th>
<th><%= t("admin.milestones.index.table_title") %></th>
<th><%= t("admin.milestones.index.table_description") %></th>
<th><%= t("admin.milestones.index.table_actions") %></th>
</tr>
</thead>
<tbody>
<% @investment.milestones.each do |milestone| %>
<tr id="<%= dom_id(milestone) %>" class="milestone">
<td>
<%= milestone.id %>
</td>
<td>
<%= link_to milestone.title, edit_admin_budget_budget_investment_budget_investment_milestone_path(@investment.budget, @investment, milestone) %>
</td>
<td class="small">
<%= milestone.description %>
</td>
<td>
<%= link_to t("admin.milestones.index.delete"), admin_budget_budget_investment_budget_investment_milestone_path(@investment.budget, @investment, milestone),
method: :delete,
class: 'button hollow alert expanded' %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<p>
<%= t('admin.milestones.index.no_milestones') %>
</p>
<% end %>

View File

@@ -47,3 +47,12 @@
<%= link_to t("admin.budget_investments.show.edit_dossier"), edit_valuation_budget_budget_investment_path(@budget, @investment) %> <%= link_to t("admin.budget_investments.show.edit_dossier"), edit_valuation_budget_budget_investment_path(@budget, @investment) %>
</p> </p>
<hr>
<h2><%= t("admin.budget_investments.show.milestone") %></h2>
<%= render 'admin/budget_investments/milestones' %>
<p>
<%= link_to t("admin.budget_investments.show.new_milestone"), new_admin_budget_budget_investment_budget_investment_milestone_path(@budget, @investment) %>
</p>

View File

@@ -16,5 +16,15 @@
<%= f.select :currency_symbol, budget_currency_symbol_select_options %> <%= f.select :currency_symbol, budget_currency_symbol_select_options %>
</div> </div>
</div> </div>
<%= f.submit nil, class: "button success" %> <div class="margin-top">
<%= f.submit nil, class: "button success" %>
<% if @budget.balloting_process? %>
<div class="float-right">
<%= link_to t("admin.budgets.winners.calculate"),
calculate_winners_admin_budget_path(@budget),
method: :put,
class: "button hollow" %>
</div>
<% end %>
</div>
<% end %> <% end %>

View File

@@ -1,7 +1,7 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th colspan="2" class="with-button"> <th colspan="3" class="with-button">
<%= group.name %> <%= group.name %>
<%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %> <%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %>
</th> </th>
@@ -21,6 +21,7 @@
<tr> <tr>
<th><%= t("admin.budgets.form.table_heading") %></th> <th><%= t("admin.budgets.form.table_heading") %></th>
<th><%= t("admin.budgets.form.table_amount") %></th> <th><%= t("admin.budgets.form.table_amount") %></th>
<th><%= t("admin.budgets.form.table_population") %></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -45,6 +46,15 @@
placeholder: t("admin.budgets.form.amount") %> placeholder: t("admin.budgets.form.amount") %>
</div> </div>
</div> </div>
<div class="row">
<div class="small-12 medium-6 column">
<label><%= t("admin.budgets.form.population") %></label>
<%= f.text_field :population,
label: false,
maxlength: 8,
placeholder: t("admin.budgets.form.population") %>
</div>
</div>
<%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %> <%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %>
<% end %> <% end %>
@@ -60,6 +70,9 @@
<td> <td>
<%= heading.price %> <%= heading.price %>
</td> </td>
<td>
<%= heading.population %>
</td>
</tr> </tr>
<% end %> <% end %>
<!-- /. headings list --> <!-- /. headings list -->

View File

@@ -17,8 +17,8 @@
<%= f.text_field :title, maxlength: Poll::Question.title_max_length %> <%= f.text_field :title, maxlength: Poll::Question.title_max_length %>
<%= f.label :valid_answers %> <%= f.label :valid_answers %>
<p class="note"><%= t("admin.questions.new.valid_answers_note") %></p> <p class="help-text" id="valid-answers-help-text"><%= t("admin.questions.new.valid_answers_note") %></p>
<%= f.text_field :valid_answers, label: false %> <%= f.text_field :valid_answers, label: false, aria: {describedby: "valid-answers-help-text"} %>
<div class="ckeditor"> <div class="ckeditor">
<%= f.cktext_area :description, <%= f.cktext_area :description,

View File

@@ -15,8 +15,8 @@
</div> </div>
<%= f.label :document_numbers %> <%= f.label :document_numbers %>
<p class="note"><%= t("admin.signature_sheets.new.document_numbers_note") %></p> <p class="help-text" id="document-numbers-help-text"><%= t("admin.signature_sheets.new.document_numbers_note") %></p>
<%= f.text_area :document_numbers, rows: "6", label: false %> <%= f.text_area :document_numbers, rows: "6", label: false, aria: {describedby: "document-numbers-help-text"} %>
<%= f.submit(class: "button", value: t("admin.signature_sheets.new.submit")) %> <%= f.submit(class: "button", value: t("admin.signature_sheets.new.submit")) %>
<% end %> <% end %>

View File

@@ -0,0 +1,22 @@
<div class="row">
<div class="small-12 column">
<ul class="tabs" data-tabs id="investments-tabs">
<li class="tabs-title is-active">
<%= link_to "#tab-comments" do %>
<h3>
<%= t("budgets.investments.show.comments_tab") %>
<span class="js-comments-count">(<%= @investment.comments_count %>)</span>
</h3>
<% end %>
</li>
<li class="tabs-title">
<%= link_to "#tab-milestones" do %>
<h3>
<%= t("budgets.investments.show.milestones_tab") %>
(<%= @investment.milestones.count %>)
</h3>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -31,7 +31,7 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :tag_list, t("budgets.investments.form.tags_label") %> <%= f.label :tag_list, t("budgets.investments.form.tags_label") %>
<p class="note"><%= t("budgets.investments.form.tags_instructions") %></p> <p class="help-text" id="tags-list-help-text"><%= t("budgets.investments.form.tags_instructions") %></p>
<div id="category_tags" class="tags"> <div id="category_tags" class="tags">
<%= f.label :category_tag_list, t("budgets.investments.form.tag_category_label") %> <%= f.label :category_tag_list, t("budgets.investments.form.tag_category_label") %>
@@ -44,6 +44,7 @@
<%= f.text_field :tag_list, value: @investment.tag_list.to_s, <%= f.text_field :tag_list, value: @investment.tag_list.to_s,
label: false, label: false,
placeholder: t("budgets.investments.form.tags_placeholder"), placeholder: t("budgets.investments.form.tags_placeholder"),
aria: {describedby: "tags-list-help-text"},
class: 'js-tag-list' %> class: 'js-tag-list' %>
</div> </div>

View File

@@ -0,0 +1,26 @@
<div class="tabs-panel tab-milestones" id="tab-milestones">
<div class="row">
<div class="small-12 column">
<% if @investment.milestones.blank? %>
<div class="callout primary text-center">
<%= t('budgets.investments.show.no_milestones') %>
</div>
<% end %>
<section class="timeline">
<ul class="no-bullet">
<% @investment.milestones.each do |milestone| %>
<li>
<div class="milestone-content">
<h3><%= milestone.title %></h3>
<span class="milestone-date">
<strong><%= t("budgets.investments.show.milestone_publish_date", publish_date: milestone.created_at.strftime("%d/%m/%Y")) %></strong>
</span>
<p><%= milestone.description %></p>
</div>
</li>
<% end %>
</ul>
</section>
</div>
</div>
</div>

View File

@@ -10,4 +10,13 @@
ballot: @ballot ballot: @ballot
} %> } %>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree, comment_flags: @comment_flags } %> <div class="tabs-content" data-tabs-content="investments-tabs" role="tablist">
<%= render "budgets/investments/filter_subnav" %>
<%= render "budgets/investments/milestones" %>
<div class="tabs-panel is-active" id="tab-comments">
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: false } %>
</div>
</div>

View File

@@ -1,14 +1,15 @@
<% commentable = comment_tree.commentable %> <% commentable = comment_tree.commentable %>
<% current_order = comment_tree.order %>
<% cache [locale_and_user_status, current_order, commentable_cache_key(commentable), comment_tree.comments, comment_tree.comment_authors, commentable.comments_count, comment_flags] do %> <% cache [locale_and_user_status, comment_tree.order, commentable_cache_key(commentable), comment_tree.comments, comment_tree.comment_authors, commentable.comments_count, comment_flags] do %>
<section class="expanded comments"> <section class="expanded comments">
<div class="row"> <div class="row">
<div id="comments" class="small-12 column"> <div id="comments" class="small-12 column">
<h2> <% if display_comments_count %>
<%= comment_tree_title_text(commentable) %> <h2>
<span class="js-comments-count">(<%= commentable.comments_count %>)</span> <%= comment_tree_title_text(commentable) %>
</h2> <span class="js-comments-count">(<%= commentable.comments_count %>)</span>
</h2>
<% end %>
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %> <%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>

View File

@@ -17,11 +17,12 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :tag_list, t("debates.form.tags_label") %> <%= f.label :tag_list, t("debates.form.tags_label") %>
<p class="note"><%= t("debates.form.tags_instructions") %></p> <p class="help-text" id="tag-list-help-text"><%= t("debates.form.tags_instructions") %></p>
<%= f.text_field :tag_list, value: @debate.tag_list.to_s, <%= f.text_field :tag_list, value: @debate.tag_list.to_s,
label: false, label: false,
placeholder: t("debates.form.tags_placeholder") %> placeholder: t("debates.form.tags_placeholder"),
aria: {describedby: "tag-list-help-text"} %>
</div> </div>
<div class="small-12 column"> <div class="small-12 column">
<% if @debate.new_record? %> <% if @debate.new_record? %>

View File

@@ -16,9 +16,7 @@
<div class="comment-actions"> <div class="comment-actions">
<a class="cancel-comment" href="#" data-cancel-annotation><%= t('legislation.annotations.comments.cancel') %></a> <a class="cancel-comment" href="#" data-cancel-annotation><%= t('legislation.annotations.comments.cancel') %></a>
<%= f.submit class: 'button publish-comment' do %> <%= f.submit value: t('legislation.annotations.comments.publish_comment'), class: 'button publish-comment' %>
<strong><%= t('legislation.annotations.comments.publish_comment') %></strong>
<% end %>
</div> </div>
<%= f.hidden_field :quote %> <%= f.hidden_field :quote %>

View File

@@ -40,7 +40,9 @@
</aside> </aside>
</div> </div>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree, comment_flags: @comment_flags } %> <%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: true } %>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -42,6 +42,7 @@
</aside> </aside>
</div> </div>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree, comment_flags: @comment_flags } %> <%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: true } %>
</section> </section>

View File

@@ -3,8 +3,10 @@
<%= form_tag management_user_invites_path do %> <%= form_tag management_user_invites_path do %>
<label><%= t('management.user_invites.new.label') %></label> <label><%= t('management.user_invites.new.label') %></label>
<p class="note"><%= t('management.user_invites.new.info') %></p> <p class="help-text" id="emails-help-text"><%= t('management.user_invites.new.info') %></p>
<%= text_area_tag "emails", nil, rows: 5, placeholder: t('management.user_invites.new.info') %> <%= text_area_tag "emails", nil, rows: 5,
placeholder: t('management.user_invites.new.info'),
aria: {describedby: "emails-help-text"} %>
<div class="small-12 medium-6"> <div class="small-12 medium-6">
<input type="submit" name="" value="<%= t('management.user_invites.new.submit') %>", class="button hollow expanded"> <input type="submit" name="" value="<%= t('management.user_invites.new.submit') %>", class="button hollow expanded">
</div> </div>

View File

@@ -9,8 +9,10 @@
<%= f.fields_for :organization do |fo| %> <%= f.fields_for :organization do |fo| %>
<%= fo.text_field :name, autofocus: true, maxlength: Organization.name_max_length, placeholder: t("devise_views.organizations.registrations.new.organization_name_label") %> <%= fo.text_field :name, autofocus: true, maxlength: Organization.name_max_length, placeholder: t("devise_views.organizations.registrations.new.organization_name_label") %>
<%= fo.label :responsible_name %> <%= fo.label :responsible_name %>
<p class="note"><%= t("devise_views.organizations.registrations.new.responsible_name_note") %></p> <p class="help-text" id="responsible-name-help-text"><%= t("devise_views.organizations.registrations.new.responsible_name_note") %></p>
<%= fo.text_field :responsible_name, placeholder: t("devise_views.organizations.registrations.new.responsible_name_label"), maxlength: Organization.responsible_name_max_length, label: false %> <%= fo.text_field :responsible_name, placeholder: t("devise_views.organizations.registrations.new.responsible_name_label"),
maxlength: Organization.responsible_name_max_length, label: false,
aria: {describedby: "responsible-name-help-text"} %>
<% end %> <% end %>
<%= f.email_field :email, placeholder: t("devise_views.organizations.registrations.new.email_label") %> <%= f.email_field :email, placeholder: t("devise_views.organizations.registrations.new.email_label") %>

View File

@@ -12,17 +12,21 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :question, t("proposals.form.proposal_question") %> <%= f.label :question, t("proposals.form.proposal_question") %>
<span class="note-marked"> <p class="help-text" id="question-help-text">
<%= t("proposals.form.proposal_question_example_html") %> <%= t("proposals.form.proposal_question_example_html") %>
</span> </p>
<%= f.text_field :question, maxlength: Proposal.question_max_length, placeholder: t("proposals.form.proposal_question"), label: false %> <%= f.text_field :question, maxlength: Proposal.question_max_length,
placeholder: t("proposals.form.proposal_question"),
label: false,
aria: {describedby: "question-help-text"} %>
</div> </div>
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :summary, t("proposals.form.proposal_summary") %> <%= f.label :summary, t("proposals.form.proposal_summary") %>
<p class="note"><%= t("proposals.form.proposal_summary_note") %></p> <p class="help-text" id="summary-help-text"><%= t("proposals.form.proposal_summary_note") %></p>
<%= f.text_area :summary, rows: 4, maxlength: 200, label: false, <%= f.text_area :summary, rows: 4, maxlength: 200, label: false,
placeholder: t('proposals.form.proposal_summary') %> placeholder: t('proposals.form.proposal_summary'),
aria: {describedby: "summary-help-text"} %>
</div> </div>
<div class="ckeditor small-12 column"> <div class="ckeditor small-12 column">
@@ -33,8 +37,9 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :video_url, t("proposals.form.proposal_video_url") %> <%= f.label :video_url, t("proposals.form.proposal_video_url") %>
<p class="note"><%= t("proposals.form.proposal_video_url_note") %></p> <p class="help-text" id="video-url-help-text"><%= t("proposals.form.proposal_video_url_note") %></p>
<%= f.text_field :video_url, placeholder: t("proposals.form.proposal_video_url"), label: false %> <%= f.text_field :video_url, placeholder: t("proposals.form.proposal_video_url"), label: false,
aria: {describedby: "video-url-help-text"} %>
</div> </div>
<div class="small-12 column"> <div class="small-12 column">
@@ -49,7 +54,7 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :tag_list, t("proposals.form.tags_label") %> <%= f.label :tag_list, t("proposals.form.tags_label") %>
<p class="note"><%= t("proposals.form.tags_instructions") %></p> <p class="help-text" id="tag-list-help-text"><%= t("proposals.form.tags_instructions") %></p>
<div id="category_tags" class="tags"> <div id="category_tags" class="tags">
<%= f.label :category_tag_list, t("proposals.form.tag_category_label") %> <%= f.label :category_tag_list, t("proposals.form.tag_category_label") %>
@@ -62,14 +67,16 @@
<%= f.text_field :tag_list, value: @proposal.tag_list.to_s, <%= f.text_field :tag_list, value: @proposal.tag_list.to_s,
label: false, label: false,
placeholder: t("proposals.form.tags_placeholder"), placeholder: t("proposals.form.tags_placeholder"),
class: 'js-tag-list' %> class: 'js-tag-list',
aria: {describedby: "tag-list-help-text"} %>
</div> </div>
<% if current_user.unverified? %> <% if current_user.unverified? %>
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :responsible_name, t("proposals.form.proposal_responsible_name") %> <%= f.label :responsible_name, t("proposals.form.proposal_responsible_name") %>
<p class="note"><%= t("proposals.form.proposal_responsible_name_note") %></p> <p class="help-text" id="responsible-name-help-text"><%= t("proposals.form.proposal_responsible_name_note") %></p>
<%= f.text_field :responsible_name, placeholder: t("proposals.form.proposal_responsible_name"), label: false %> <%= f.text_field :responsible_name, placeholder: t("proposals.form.proposal_responsible_name"), label: false,
aria: {describedby: "responsible-name-help-text"} %>
</div> </div>
<% end %> <% end %>

View File

@@ -12,35 +12,39 @@
<% cache [locale_and_user_status(@proposal), @proposal, @proposal.author, Flag.flagged?(current_user, @proposal), @proposal_votes] do %> <% cache [locale_and_user_status(@proposal), @proposal, @proposal.author, Flag.flagged?(current_user, @proposal), @proposal_votes] do %>
<div class="proposal-show"> <div class="proposal-show">
<div id="<%= dom_id(@proposal) %>" class="row"> <div id="<%= dom_id(@proposal) %>" class="row">
<div class="small-12 medium-9 column"> <div class="small-12 medium-8 column">
<h1><%= t("proposals.proposal.created") %></h1> <h1><%= t("proposals.proposal.created") %></h1>
<h2><%= @proposal.title %></h2>
<p> <p>
<%= t("proposals.show.code") %> <span class="lead"><%= t("proposals.proposal.share.guide") %></span><br>
<strong><%= @proposal.code %></strong> <%= t("proposals.proposal.share.edit") %>
</p> </p>
<p><%= t("proposals.proposal.share.guide").html_safe %></p>
<%= render partial: 'shared/social_share', locals: { <%= render partial: 'shared/social_share', locals: {
title: @proposal.title, title: @proposal.title,
url: proposal_url(@proposal) url: proposal_url(@proposal)
} %> } %>
<br/>
<% if @proposal_improvement_path.present? %> <% if @proposal_improvement_path.present? %>
<p><%= t('proposals.proposal.improve_info', improve_info_link: link_to(t('proposals.proposal.improve_info_link'), @proposal_improvement_path)).html_safe %></p> <div class="callout highlight margin-top text-center">
<p class="lead"><strong><%= t("proposals.proposal.improve_info") %></strong></p>
<%= link_to t("proposals.proposal.improve_info_link"), @proposal_improvement_path, class: "button" %>
</div>
<% end %> <% end %>
<p> <div class="small margin-bottom">
<%= link_to proposal_path(@proposal), class: 'proposal' do %> <%= link_to t("proposals.proposal.share.view_proposal"), proposal_path(@proposal) %>
<%= t("proposals.proposal.share.view_proposal") %> </div>
<% end %> </div>
</p>
<div class="small-12 medium-4 column">
<div class="callout light">
<p>
<strong><%= @proposal.title %></strong><br>
<%= t("proposals.show.code") %> <%= @proposal.code %>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,10 +1,12 @@
<div class="small-12 column" > <div class="small-12 column" >
<% if @search_terms && @resources.any? %> <% if @search_terms && @resources.any? %>
<div class="alert-box radius warning"> <div class="callout warning">
<p class="note-marked"> <p>
<%= t("shared.suggest.#{resource_name}.found", <strong>
count: @resources.count, <%= t("shared.suggest.#{resource_name}.found",
query: @search_terms)%> count: @resources.count,
query: @search_terms)%>
</strong>
</p> </p>
<ul> <ul>
@@ -14,11 +16,13 @@
</ul> </ul>
<% if @resources.count > @limit %> <% if @resources.count > @limit %>
<p class="note-marked"> <p>
<%= t("shared.suggest.#{resource_name}.message", <strong>
count: @resources.count, <%= t("shared.suggest.#{resource_name}.message",
query: @search_terms, count: @resources.count,
limit: @limit) %> query: @search_terms,
limit: @limit) %>
</strong>
<%= link_to t("shared.suggest.#{resource_name}.see_all"), <%= link_to t("shared.suggest.#{resource_name}.see_all"),
polymorphic_url(resource_model, search: @search_terms)%> polymorphic_url(resource_model, search: @search_terms)%>
</p> </p>

View File

@@ -18,8 +18,10 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :password, t("devise_views.users.registrations.edit.password_label") %> <%= f.label :password, t("devise_views.users.registrations.edit.password_label") %>
<p class="note"><%= t("devise_views.users.registrations.edit.leave_blank") %></p> <p class="help-text" id="password-help-text"><%= t("devise_views.users.registrations.edit.leave_blank") %></p>
<%= f.password_field :password, autocomplete: "off", label: false, placeholder: t("devise_views.users.registrations.edit.password_label") %> <%= f.password_field :password, autocomplete: "off", label: false,
placeholder: t("devise_views.users.registrations.edit.password_label"),
aria: {describedby: "password-help-text"} %>
</div> </div>
<div class="small-12 column"> <div class="small-12 column">
@@ -29,8 +31,10 @@
<div class="small-12 column"> <div class="small-12 column">
<%= f.label :current_password, t("devise_views.users.registrations.edit.current_password_label") %> <%= f.label :current_password, t("devise_views.users.registrations.edit.current_password_label") %>
<p class="note"><%= t("devise_views.users.registrations.edit.need_current") %></p> <p class="help-text" id="current-password-help-text"><%= t("devise_views.users.registrations.edit.need_current") %></p>
<%= f.password_field :current_password, label: false, autocomplete: "off", placeholder: t("devise_views.users.registrations.edit.current_password_label") %> <%= f.password_field :current_password, label: false, autocomplete: "off",
placeholder: t("devise_views.users.registrations.edit.current_password_label"),
aria: {describedby: "current-password-help-text"} %>
</div> </div>
<div class="small-12 column"> <div class="small-12 column">

View File

@@ -18,8 +18,11 @@
<%= f.hidden_field :locale, value: I18n.locale %> <%= f.hidden_field :locale, value: I18n.locale %>
<%= f.label :username %> <%= f.label :username %>
<p class="note"><%= t("devise_views.users.registrations.new.username_note") %></p> <p class="help-text" id="username-help-text"><%= t("devise_views.users.registrations.new.username_note") %></p>
<%= f.text_field :username, autofocus: true, 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,
aria: {describedby: "username-help-text"} %>
<%= f.invisible_captcha :family_name %> <%= f.invisible_captcha :family_name %>

Some files were not shown because too many files have changed in this diff Show More