Merge branch 'master' into tracking_user_verifications_and_others
Conflicts: app/controllers/admin/stats_controller.rb db/dev_seeds.rb
This commit is contained in:
9
Gemfile
9
Gemfile
@@ -19,7 +19,7 @@ gem 'jquery-ui-rails'
|
||||
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
|
||||
gem 'turbolinks'
|
||||
|
||||
gem 'devise', '~> 3.5.6'
|
||||
gem 'devise', '~> 3.5.7'
|
||||
# Use ActiveModel has_secure_password
|
||||
# gem 'bcrypt', '~> 3.1.7'
|
||||
gem 'omniauth'
|
||||
@@ -39,7 +39,7 @@ gem 'ckeditor', '~> 4.1.5'
|
||||
gem 'cancancan'
|
||||
gem 'social-share-button', git: 'https://github.com/huacnlee/social-share-button.git', ref: 'e46a6a3e82b86023bc'
|
||||
gem 'initialjs-rails', '0.2.0.1'
|
||||
gem 'unicorn', '~> 5.0.1'
|
||||
gem 'unicorn', '~> 5.1.0'
|
||||
gem 'paranoia'
|
||||
gem 'rinku', require: 'rails_rinku'
|
||||
gem 'savon'
|
||||
@@ -52,13 +52,14 @@ gem 'newrelic_rpm', '~> 3.14'
|
||||
gem 'whenever', require: false
|
||||
gem 'pg_search'
|
||||
|
||||
gem 'ahoy_matey', '~> 1.2.1'
|
||||
gem 'ahoy_matey', '~> 1.4.0'
|
||||
gem 'groupdate' # group temporary data
|
||||
gem 'tolk' # Web interface for translations
|
||||
|
||||
gem 'browser'
|
||||
gem 'turnout'
|
||||
gem 'redcarpet'
|
||||
|
||||
group :development, :test do
|
||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||
gem 'byebug'
|
||||
@@ -73,7 +74,7 @@ group :development, :test do
|
||||
gem 'quiet_assets'
|
||||
gem 'letter_opener_web', '~> 1.3.0'
|
||||
gem 'i18n-tasks'
|
||||
gem 'capistrano', '3.4.0', require: false
|
||||
gem 'capistrano', '3.4.1', require: false
|
||||
gem "capistrano-bundler", '1.1.4', require: false
|
||||
gem "capistrano-rails", '1.1.6', require: false
|
||||
gem "capistrano-rvm", require: false
|
||||
|
||||
88
Gemfile.lock
88
Gemfile.lock
@@ -49,14 +49,15 @@ GEM
|
||||
activerecord (>= 3.2, < 5)
|
||||
acts_as_votable (0.10.0)
|
||||
addressable (2.4.0)
|
||||
ahoy_matey (1.2.1)
|
||||
ahoy_matey (1.4.0)
|
||||
addressable
|
||||
browser (>= 0.4.0)
|
||||
errbase
|
||||
browser (~> 2.0)
|
||||
geocoder
|
||||
rails
|
||||
rack-attack
|
||||
railties
|
||||
referer-parser (>= 0.3.0)
|
||||
request_store
|
||||
safely_block
|
||||
user_agent_parser
|
||||
uuidtools
|
||||
akami (1.3.1)
|
||||
@@ -70,15 +71,15 @@ GEM
|
||||
babel-transpiler (0.7.0)
|
||||
babel-source (>= 4.0, < 6)
|
||||
execjs (~> 2.0)
|
||||
bcrypt (3.1.10)
|
||||
browser (1.1.0)
|
||||
bcrypt (3.1.11)
|
||||
browser (2.0.3)
|
||||
builder (3.2.2)
|
||||
bullet (5.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.9.0)
|
||||
byebug (8.2.2)
|
||||
byebug (8.2.4)
|
||||
cancancan (1.13.1)
|
||||
capistrano (3.4.0)
|
||||
capistrano (3.4.1)
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (~> 1.3)
|
||||
@@ -91,9 +92,9 @@ GEM
|
||||
capistrano-rvm (0.1.2)
|
||||
capistrano (~> 3.0)
|
||||
sshkit (~> 1.2)
|
||||
capistrano3-delayed-job (1.6.0)
|
||||
capistrano3-delayed-job (1.7.0)
|
||||
capistrano (>= 3.0.0)
|
||||
capybara (2.6.2)
|
||||
capybara (2.7.0)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
@@ -125,14 +126,14 @@ GEM
|
||||
tins (~> 1.6.0)
|
||||
daemons (1.2.3)
|
||||
dalli (2.7.6)
|
||||
database_cleaner (1.5.1)
|
||||
database_cleaner (1.5.2)
|
||||
debug_inspector (0.0.2)
|
||||
delayed_job (4.1.1)
|
||||
activesupport (>= 3.0, < 5.0)
|
||||
delayed_job_active_record (4.1.0)
|
||||
activerecord (>= 3.0, < 5)
|
||||
delayed_job (>= 3.0, < 5)
|
||||
devise (3.5.6)
|
||||
devise (3.5.7)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 3.2.6, < 5)
|
||||
@@ -154,16 +155,16 @@ GEM
|
||||
errbase (0.0.3)
|
||||
erubis (2.7.0)
|
||||
execjs (2.6.0)
|
||||
factory_girl (4.5.0)
|
||||
factory_girl (4.7.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.6.0)
|
||||
factory_girl (~> 4.5.0)
|
||||
factory_girl_rails (4.7.0)
|
||||
factory_girl (~> 4.7.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.6.3)
|
||||
i18n (~> 0.5)
|
||||
faraday (0.9.2)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
foundation-rails (6.2.0.1)
|
||||
foundation-rails (6.2.1.0)
|
||||
railties (>= 3.1.0)
|
||||
sass (>= 3.3.0, < 3.5)
|
||||
sprockets-es6 (>= 0.9.0)
|
||||
@@ -176,7 +177,7 @@ GEM
|
||||
fuubar (2.0.0)
|
||||
rspec (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
geocoder (1.3.1)
|
||||
geocoder (1.3.4)
|
||||
globalid (0.3.6)
|
||||
activesupport (>= 4.1.0)
|
||||
groupdate (2.5.2)
|
||||
@@ -208,7 +209,7 @@ GEM
|
||||
jquery-ui-rails (5.0.5)
|
||||
railties (>= 3.2.16)
|
||||
json (1.8.3)
|
||||
jwt (1.5.3)
|
||||
jwt (1.5.4)
|
||||
kaminari (0.16.3)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -223,9 +224,11 @@ GEM
|
||||
railties (>= 3.2)
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
mime-types (2.99.1)
|
||||
mail (2.6.4)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mime-types (3.0)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0221)
|
||||
mini_portile2 (2.0.0)
|
||||
minitest (5.8.4)
|
||||
multi_json (1.11.2)
|
||||
@@ -233,8 +236,8 @@ GEM
|
||||
multipart-post (2.0.0)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (3.0.2)
|
||||
newrelic_rpm (3.15.0.314)
|
||||
net-ssh (3.1.1)
|
||||
newrelic_rpm (3.15.1.316)
|
||||
nokogiri (1.6.7.2)
|
||||
mini_portile2 (~> 2.0.0.rc2)
|
||||
nori (2.6.0)
|
||||
@@ -284,6 +287,8 @@ GEM
|
||||
rack (1.6.4)
|
||||
rack-accept (0.4.5)
|
||||
rack (>= 0.4)
|
||||
rack-attack (4.4.1)
|
||||
rack
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (4.2.6)
|
||||
@@ -310,12 +315,12 @@ GEM
|
||||
activesupport (= 4.2.6)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
raindrops (0.15.0)
|
||||
rake (11.1.1)
|
||||
raindrops (0.16.0)
|
||||
rake (11.1.2)
|
||||
redcarpet (3.3.4)
|
||||
referer-parser (0.3.0)
|
||||
request_store (1.3.0)
|
||||
responders (2.1.1)
|
||||
request_store (1.3.1)
|
||||
responders (2.1.2)
|
||||
railties (>= 4.2.0, < 5.1)
|
||||
rinku (1.7.3)
|
||||
rollbar (2.8.3)
|
||||
@@ -343,7 +348,9 @@ GEM
|
||||
rspec-support (3.4.1)
|
||||
ruby-progressbar (1.7.5)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.4.21)
|
||||
safely_block (0.1.0)
|
||||
errbase
|
||||
sass (3.4.22)
|
||||
sass-rails (5.0.4)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
sass (~> 3.1)
|
||||
@@ -365,10 +372,10 @@ GEM
|
||||
json (~> 1.8)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.0)
|
||||
spring (1.6.4)
|
||||
spring (1.7.1)
|
||||
spring-commands-rspec (1.0.4)
|
||||
spring (>= 0.9.1)
|
||||
sprockets (3.5.2)
|
||||
sprockets (3.6.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-es6 (0.9.0)
|
||||
@@ -379,7 +386,7 @@ GEM
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sshkit (1.8.1)
|
||||
sshkit (1.9.0)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
term-ansicolor (1.3.2)
|
||||
@@ -395,17 +402,16 @@ GEM
|
||||
safe_yaml (>= 0.8.6)
|
||||
turbolinks (2.5.3)
|
||||
coffee-rails
|
||||
turnout (2.2.1)
|
||||
turnout (2.3.0)
|
||||
rack (~> 1.3)
|
||||
rack-accept (~> 0.4)
|
||||
tilt (>= 1.4, < 3)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (2.7.2)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
unicorn (5.0.1)
|
||||
uglifier (3.0.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicorn (5.1.0)
|
||||
kgio (~> 2.6)
|
||||
rack
|
||||
raindrops (~> 0.7)
|
||||
uniform_notifier (1.9.0)
|
||||
user_agent_parser (2.3.0)
|
||||
@@ -433,13 +439,13 @@ PLATFORMS
|
||||
DEPENDENCIES
|
||||
acts-as-taggable-on
|
||||
acts_as_votable
|
||||
ahoy_matey (~> 1.2.1)
|
||||
ahoy_matey (~> 1.4.0)
|
||||
ancestry
|
||||
browser
|
||||
bullet
|
||||
byebug
|
||||
cancancan
|
||||
capistrano (= 3.4.0)
|
||||
capistrano (= 3.4.1)
|
||||
capistrano-bundler (= 1.1.4)
|
||||
capistrano-rails (= 1.1.6)
|
||||
capistrano-rvm
|
||||
@@ -452,7 +458,7 @@ DEPENDENCIES
|
||||
dalli
|
||||
database_cleaner
|
||||
delayed_job_active_record (~> 4.1.0)
|
||||
devise (~> 3.5.6)
|
||||
devise (~> 3.5.7)
|
||||
devise-async
|
||||
email_spec
|
||||
factory_girl_rails
|
||||
@@ -494,7 +500,7 @@ DEPENDENCIES
|
||||
turbolinks
|
||||
turnout
|
||||
uglifier (>= 1.3.0)
|
||||
unicorn (~> 5.0.1)
|
||||
unicorn (~> 5.1.0)
|
||||
web-console (~> 3.0)
|
||||
whenever
|
||||
|
||||
|
||||
20
README.md
20
README.md
@@ -48,7 +48,7 @@ bin/rails s
|
||||
|
||||
```
|
||||
|
||||
Prerequisites for testing: install PhantomJS >= 2.0
|
||||
Prerequisites for testing: install PhantomJS >= 1.9.8
|
||||
|
||||
Run the tests with:
|
||||
|
||||
@@ -56,7 +56,23 @@ Run the tests with:
|
||||
bin/rspec
|
||||
```
|
||||
|
||||
## Licence
|
||||
You can use the default admin user from the seeds file:
|
||||
|
||||
**user:** admin@madrid.es
|
||||
**pass:** 12345678
|
||||
|
||||
But for some actions like voting, you will need a verified user, the seeds file also includes one:
|
||||
|
||||
**user:** verified@madrid.es
|
||||
**pass:** 12345678
|
||||
|
||||
### OAuth
|
||||
|
||||
To test authentication services with external OAuth suppliers - right now Twitter, Facebook and Google - you'll need to create an "application" in each of the supported platforms and set the *key* and *secret* provided in your *secrets.yml*
|
||||
|
||||
In the case of Google, verify that the APIs *Contacts API* and *Google+ API* are enabled for the application.
|
||||
|
||||
## License
|
||||
|
||||
Code published under AFFERO GPL v3 (see [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt))
|
||||
|
||||
|
||||
13
README_ES.md
13
README_ES.md
@@ -47,7 +47,7 @@ Para ejecutar la aplicación en local:
|
||||
bin/rails s
|
||||
```
|
||||
|
||||
Prerequisitos para los tests: tener instalado PhantomJS >= 2.0
|
||||
Prerequisitos para los tests: tener instalado PhantomJS >= 1.9.8
|
||||
|
||||
Para ejecutar los tests:
|
||||
|
||||
@@ -55,6 +55,17 @@ Para ejecutar los tests:
|
||||
bin/rspec
|
||||
```
|
||||
|
||||
Puedes usar el usuario administrador por defecto del fichero seeds:
|
||||
|
||||
**user:** admin@madrid.es
|
||||
**pass:** 12345678
|
||||
|
||||
Pero para ciertas acciones, como apoyar, necesitarás un usuario verificado, el fichero seeds proporciona uno:
|
||||
|
||||
**user:** verified@madrid.es
|
||||
**pass:** 12345678
|
||||
|
||||
|
||||
### OAuth
|
||||
|
||||
Para probar los servicios de autenticación mediante proveedores externos OAuth — en este momento Twitter, Facebook y Google —, necesitas crear una "aplicación" en cada una de las plataformas soportadas y configurar la *key* y el *secret* proporcionados en tu *secrets.yml*
|
||||
|
||||
Binary file not shown.
@@ -48,4 +48,5 @@
|
||||
<glyph glyph-name="budget" unicode="S" d="M33 256l223 0 0 223c-5 1-11 1-16 1-115 0-208-93-208-208 0-5 0-11 1-16z m77-146c38-48 96-78 162-78 115 0 208 93 208 208 0 66-30 124-78 162-31 26-71 42-114 45l0-223-223 0c3-43 19-83 45-114z"/>
|
||||
<glyph glyph-name="notification" unicode="n" d="M256 48c23 0 41 19 41 42l-82 0c0-23 18-42 41-42z m135 125l0 114c0 64-45 118-104 131l0 15c0 17-13 31-31 31-18 0-31-14-31-31l0-15c-59-13-104-67-104-131l0-114-41-42 0-21 352 0 0 21z"/>
|
||||
<glyph glyph-name="no-notification" unicode="x" d="M257 392c7 0 24-5 24-5 46-10 78-52 78-100l0-127 9-10 8-8-240 0 8 8 9 10 0 127c0 48 33 90 78 100 0 0 18 5 24 5m1 72c-18 0-31-14-31-31l0-15c-59-13-104-67-104-131l0-114-41-42 0-21 352 0 0 21-41 42 0 114c0 64-45 118-104 131l0 15c0 17-13 31-31 31z m41-374l-82 0c0-23 18-42 41-42 23 0 41 19 41 42z"/>
|
||||
<glyph glyph-name="whatsapp" unicode="P" d="M318 234c2 0 12-4 28-13 16-8 24-13 25-15 1-1 1-2 1-4 0-7-2-14-5-22-3-7-10-14-20-19-11-5-20-7-29-7-11 0-29 6-55 17-18 9-34 20-48 34-14 14-28 32-42 53-14 20-21 39-21 55l0 3c1 17 8 32 21 45 5 4 10 6 15 6 1 0 3 0 5 0 3-1 5-1 6-1 3 0 6 0 7-2 2-1 3-3 5-7 1-4 5-13 9-26 5-13 7-20 7-21 0-4-3-9-9-16-7-7-10-12-10-14 0-1 0-2 1-4 7-14 16-27 29-39 11-10 25-20 43-29 3-1 5-2 7-2 3 0 8 5 15 14 8 9 13 14 15 14z m-58-152c24 0 47 5 70 15 22 9 41 22 57 38 16 16 29 35 38 57 10 22 14 46 14 70 0 24-4 47-14 69-9 22-22 42-38 58-16 16-35 28-57 38-23 9-46 14-70 14-24 0-47-5-70-14-22-10-41-22-57-38-16-16-29-36-38-58-10-22-14-45-14-69 0-39 11-74 34-105l-23-67 69 22c31-20 63-30 99-30z m0 395c29 0 57-6 84-17 26-11 49-27 68-46 20-19 35-42 46-69 12-26 17-54 17-83 0-29-5-57-17-84-11-26-26-49-46-69-19-19-42-34-68-46-27-11-55-17-84-17-37 0-72 9-104 27l-119-38 38 116c-20 33-30 71-30 111 0 29 5 57 17 83 11 27 26 50 46 69 19 19 42 35 68 46 27 11 55 17 84 17z"/>
|
||||
</font></defs></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
Binary file not shown.
Binary file not shown.
@@ -43,6 +43,7 @@
|
||||
//= require forms
|
||||
//= require tracks
|
||||
//= require valuation_spending_proposal_form
|
||||
//= require embed_video
|
||||
|
||||
var initialize_modules = function() {
|
||||
App.Comments.initialize();
|
||||
@@ -61,6 +62,7 @@ var initialize_modules = function() {
|
||||
App.Forms.initialize();
|
||||
App.Tracks.initialize();
|
||||
App.ValuationSpendingProposalForm.initialize();
|
||||
App.EmbedVideo.initialize();
|
||||
};
|
||||
|
||||
$(function(){
|
||||
|
||||
7
app/assets/javascripts/embed_video.js.coffee
Normal file
7
app/assets/javascripts/embed_video.js.coffee
Normal file
@@ -0,0 +1,7 @@
|
||||
App.EmbedVideo =
|
||||
|
||||
initialize: ->
|
||||
$('#js-embedded-video').each ->
|
||||
code = $(this).data("video-code")
|
||||
$('#js-embedded-video').html(code)
|
||||
|
||||
@@ -5,11 +5,13 @@ App.Votes =
|
||||
$("div.anonymous-votes", votes).show();
|
||||
$("div.organizations-votes", votes).show();
|
||||
$("div.not-logged", votes).show();
|
||||
$("div.no-supports-allowed", votes).show();
|
||||
$("div.logged", votes).hide();
|
||||
, ->
|
||||
$("div.anonymous-votes", votes).hide();
|
||||
$("div.organizations-votes", votes).hide();
|
||||
$("div.not-logged", votes).hide();
|
||||
$("div.no-supports-allowed", votes).hide();
|
||||
$("div.logged", votes).show();
|
||||
|
||||
initialize: ->
|
||||
|
||||
@@ -116,7 +116,7 @@ body.admin {
|
||||
[class^="icon-"] {
|
||||
display: inline-block;
|
||||
font-size: rem-calc(24);
|
||||
padding-right: rem-calc(24);
|
||||
padding-right: rem-calc(12);
|
||||
padding-top: rem-calc(4);
|
||||
padding-left: 12px\9 !important;
|
||||
padding-right: 12px\9 !important;
|
||||
@@ -349,3 +349,22 @@ body.admin {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
body.admin {
|
||||
|
||||
.investment-projects-list.medium-9 {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.admin-content .select-geozone {
|
||||
|
||||
a {
|
||||
display: block;
|
||||
|
||||
&.active {
|
||||
color: $brand;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,3 +160,6 @@
|
||||
.icon-no-notification:before {
|
||||
content: "\78";
|
||||
}
|
||||
.icon-whatsapp:before {
|
||||
content: "\50";
|
||||
}
|
||||
|
||||
@@ -164,10 +164,12 @@
|
||||
|
||||
.progress {
|
||||
background-color: rgba(255,255,255,.8);
|
||||
height: rem-calc(12);
|
||||
height: $line-height/2;
|
||||
|
||||
.meter {
|
||||
background: $votes-like;
|
||||
display: block;
|
||||
height: $line-height/2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +240,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.anonymous-votes, .organizations-votes {
|
||||
.anonymous-votes, .organizations-votes, .no-supports-allowed {
|
||||
background: $warning-bg;
|
||||
color: $warning-color;
|
||||
height: 100%;
|
||||
@@ -274,7 +276,7 @@
|
||||
|
||||
.debate-new, .debate-edit,
|
||||
.proposal-new, .proposal-edit,
|
||||
.spending-proposal-new, .spending-proposal-edit {
|
||||
.spending-proposal-new, .spending-proposal-edit {
|
||||
|
||||
.back {
|
||||
@include back;
|
||||
@@ -335,13 +337,30 @@
|
||||
// 03. Show participation
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
.debate-show, .proposal-show {
|
||||
.debate-show, .proposal-show, .investment-project-show {
|
||||
|
||||
p {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.social-share-full .social-share-button {
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.whatsapp:before {
|
||||
background-color: #43d854;
|
||||
color: white;
|
||||
font-size: 1.7em;
|
||||
margin-left: rem-calc(0.5);
|
||||
padding: rem-calc(9.5) rem-calc(9.8);
|
||||
vertical-align: rem-calc(10);
|
||||
}
|
||||
|
||||
.edit-debate, .edit-proposal {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.debate-info, .proposal-info {
|
||||
.debate-info, .proposal-info, .investment-project-info {
|
||||
clear: both;
|
||||
color: $text-medium;
|
||||
font-size: $small-font-size;
|
||||
@@ -532,7 +551,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.debate, .proposal {
|
||||
.debate, .proposal, .investment-project {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
|
||||
@@ -551,7 +570,7 @@
|
||||
padding-bottom: rem-calc(12);
|
||||
}
|
||||
|
||||
.label-debate, .label-proposal {
|
||||
.label-debate, .label-proposal, .label-investment-project {
|
||||
background: none;
|
||||
clear: both;
|
||||
display: block;
|
||||
@@ -573,6 +592,10 @@
|
||||
color: $proposals;
|
||||
}
|
||||
|
||||
.label-investment-project {
|
||||
color: $budget;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
@@ -582,7 +605,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.debate-content, .proposal-content {
|
||||
.debate-content, .proposal-content, .investment-project-content {
|
||||
margin: 0;
|
||||
min-height: rem-calc(180);
|
||||
position: relative;
|
||||
@@ -592,24 +615,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
.icon-debates, .icon-proposals {
|
||||
.icon-debates, .icon-proposals, .icon-budget {
|
||||
font-size: rem-calc(18);
|
||||
line-height: $line-height;
|
||||
position: absolute;
|
||||
margin-left: rem-calc(6);
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.icon-debates {
|
||||
color: $debates;
|
||||
left: rem-calc(48);
|
||||
}
|
||||
|
||||
.icon-proposals {
|
||||
color: $proposals;
|
||||
left: rem-calc(72);
|
||||
}
|
||||
|
||||
.debate-info, .proposal-info {
|
||||
.icon-budget {
|
||||
color: $budget;
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
.debate-info, .proposal-info, .investment-project-info {
|
||||
color: $text-medium;
|
||||
font-size: $small-font-size;
|
||||
margin: rem-calc(6) 0 0;
|
||||
@@ -624,7 +650,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.debate-description, .proposal-description {
|
||||
.debate-description, .proposal-description, .investment-project-description {
|
||||
color: $text;
|
||||
font-size: rem-calc(13);
|
||||
height: rem-calc(72);
|
||||
@@ -785,6 +811,62 @@
|
||||
}
|
||||
}
|
||||
|
||||
.investment-project, .investment-project-show {
|
||||
|
||||
.supports {
|
||||
@include supports;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-left: 1px solid $border;
|
||||
margin: 0 rem-calc(-12);
|
||||
min-height: rem-calc(180);
|
||||
padding-top: $line-height*2;
|
||||
|
||||
&:after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.button-support {
|
||||
background: $budget;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
background: $budget-hover;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
|
||||
.total-supports {
|
||||
color: $budget;
|
||||
font-size: $base-font-size;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.supported {
|
||||
color: $budget;
|
||||
}
|
||||
|
||||
.no-supports-allowed {
|
||||
background: rgba(69,67,114,.96);
|
||||
color: white;
|
||||
padding: rem-calc(12);
|
||||
}
|
||||
|
||||
.no-supports-allowed p, .no-supports-allowed a {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.investment-project-show .supports {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.proposals-summary {
|
||||
|
||||
.panel {
|
||||
@@ -792,6 +874,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.investment-project .supports .total-supports.no-button,
|
||||
.investment-project-show .supports .total-supports.no-button {
|
||||
display: block;
|
||||
margin-top: $line-height*1.5;
|
||||
}
|
||||
|
||||
// 05. Featured
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ $proposals: #FFA42D;
|
||||
$proposals-border: #CC8425;
|
||||
|
||||
$budget: #454372;
|
||||
$budget-hover: #7571BF;
|
||||
|
||||
$highlight: #E7F2FC;
|
||||
$featured: #FED900;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
class Admin::Api::StatsController < Admin::Api::BaseController
|
||||
|
||||
def show
|
||||
unless params[:events].present? || params[:visits].present?
|
||||
unless params[:events].present? ||
|
||||
params[:visits].present? ||
|
||||
params[:spending_proposals].present?
|
||||
return render json: {}, status: :bad_request
|
||||
end
|
||||
|
||||
@@ -18,7 +20,10 @@ class Admin::Api::StatsController < Admin::Api::BaseController
|
||||
ds.add "Visits", Visit.group_by_day(:started_at).count
|
||||
end
|
||||
|
||||
if params[:spending_proposals].present?
|
||||
ds.add "Spending proposals", SpendingProposal.group_by_day(:created_at).count
|
||||
end
|
||||
|
||||
render json: ds.build
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ class Admin::SpendingProposalsController < Admin::BaseController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
@spending_proposals = SpendingProposal.search(params, @current_filter).order(created_at: :desc).page(params[:page])
|
||||
@spending_proposals = SpendingProposal.scoped_filter(params, @current_filter).order(created_at: :desc).page(params[:page])
|
||||
end
|
||||
|
||||
def show
|
||||
@@ -21,10 +21,8 @@ class Admin::SpendingProposalsController < Admin::BaseController
|
||||
|
||||
def update
|
||||
if @spending_proposal.update(spending_proposal_params)
|
||||
path = admin_spending_proposal_path( @spending_proposal,
|
||||
{ anchor: 'classification' }.merge(SpendingProposal.filter_params(params)))
|
||||
|
||||
redirect_to path, notice: t("flash.actions.update.spending_proposal")
|
||||
redirect_to admin_spending_proposal_path(@spending_proposal, SpendingProposal.filter_params(params)),
|
||||
notice: t("flash.actions.update.spending_proposal")
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
@@ -33,7 +31,7 @@ class Admin::SpendingProposalsController < Admin::BaseController
|
||||
private
|
||||
|
||||
def spending_proposal_params
|
||||
params.require(:spending_proposal).permit(:administrator_id, :tag_list, valuator_ids: [])
|
||||
params.require(:spending_proposal).permit(:title, :description, :external_url, :geozone_id, :association_name, :administrator_id, :tag_list, valuator_ids: [])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -18,10 +18,10 @@ class Admin::StatsController < Admin::BaseController
|
||||
@verified_users = User.with_hidden.level_two_or_three_verified.count
|
||||
@unverified_users = User.with_hidden.unverified.count
|
||||
@users = User.with_hidden.count
|
||||
|
||||
@user_ids_who_voted_proposals =
|
||||
ActsAsVotable::Vote.where(votable_type: 'Proposal').pluck(:voter_id).uniq.count
|
||||
@user_ids_who_didnt_vote_proposals = @verified_users - @user_ids_who_voted_proposals
|
||||
end
|
||||
@spending_proposals = SpendingProposal.count
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -77,6 +77,10 @@ class ApplicationController < ActionController::Base
|
||||
@proposal_votes = current_user ? current_user.proposal_votes(proposals) : {}
|
||||
end
|
||||
|
||||
def set_spending_proposal_votes(spending_proposals)
|
||||
@spending_proposal_votes = current_user ? current_user.spending_proposal_votes(spending_proposals) : {}
|
||||
end
|
||||
|
||||
def set_comment_flags(comments)
|
||||
@comment_flags = current_user ? current_user.comment_flags(comments) : {}
|
||||
end
|
||||
|
||||
@@ -65,8 +65,7 @@ module CommentableActions
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def map
|
||||
def map
|
||||
@resource = resource_model.new
|
||||
@tag_cloud = tag_cloud
|
||||
end
|
||||
|
||||
13
app/controllers/management/account_controller.rb
Normal file
13
app/controllers/management/account_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class Management::AccountController < Management::BaseController
|
||||
|
||||
before_action :only_verified_users
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
private
|
||||
def only_verified_users
|
||||
check_verified_user t("management.account.alert.unverified_user")
|
||||
end
|
||||
|
||||
end
|
||||
@@ -20,6 +20,16 @@ class Management::BaseController < ActionController::Base
|
||||
@managed_user ||= Verification::Management::ManagedUser.find(session[:document_type], session[:document_number])
|
||||
end
|
||||
|
||||
def current_user
|
||||
managed_user
|
||||
end
|
||||
|
||||
def check_verified_user(alert_msg)
|
||||
unless current_user.level_two_or_three_verified?
|
||||
redirect_to management_document_verifications_path, alert: alert_msg
|
||||
end
|
||||
end
|
||||
|
||||
def set_locale
|
||||
if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym)
|
||||
session[:locale] = params[:locale]
|
||||
|
||||
@@ -2,7 +2,7 @@ class Management::ProposalsController < Management::BaseController
|
||||
include HasOrders
|
||||
include CommentableActions
|
||||
|
||||
before_action :check_verified_user, except: :print
|
||||
before_action :only_verified_users, except: :print
|
||||
before_action :set_proposal, only: [:vote, :show]
|
||||
before_action :parse_search_terms, only: :index
|
||||
before_action :load_categories, only: [:new, :edit]
|
||||
@@ -40,14 +40,8 @@ class Management::ProposalsController < Management::BaseController
|
||||
Proposal
|
||||
end
|
||||
|
||||
def check_verified_user
|
||||
unless current_user.level_two_or_three_verified?
|
||||
redirect_to management_document_verifications_path, alert: t("management.proposals.alert.unverified_user")
|
||||
end
|
||||
end
|
||||
|
||||
def current_user
|
||||
managed_user
|
||||
def only_verified_users
|
||||
check_verified_user t("management.proposals.alert.unverified_user")
|
||||
end
|
||||
|
||||
### Duplicated in application_controller. Move to a concern.
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
class Management::SpendingProposalsController < Management::BaseController
|
||||
|
||||
before_action :check_verified_user
|
||||
before_action :only_verified_users, except: :print
|
||||
before_action :set_spending_proposal, only: [:vote, :show]
|
||||
|
||||
def index
|
||||
@spending_proposals = apply_filters_and_search(SpendingProposal).order(cached_votes_up: :desc).page(params[:page]).for_render
|
||||
set_spending_proposal_votes(@spending_proposals)
|
||||
end
|
||||
|
||||
def new
|
||||
@spending_proposal = SpendingProposal.new
|
||||
@@ -18,23 +24,55 @@ class Management::SpendingProposalsController < Management::BaseController
|
||||
end
|
||||
|
||||
def show
|
||||
@spending_proposal = SpendingProposal.find(params[:id])
|
||||
set_spending_proposal_votes(@spending_proposal)
|
||||
end
|
||||
|
||||
def vote
|
||||
@spending_proposal.register_vote(current_user, 'yes')
|
||||
set_spending_proposal_votes(@spending_proposal)
|
||||
end
|
||||
|
||||
def print
|
||||
params[:geozone] ||= 'all'
|
||||
@spending_proposals = apply_filters_and_search(SpendingProposal).order(cached_votes_up: :desc).for_render.limit(15)
|
||||
set_spending_proposal_votes(@spending_proposals)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_spending_proposal
|
||||
@spending_proposal = SpendingProposal.find(params[:id])
|
||||
end
|
||||
|
||||
def spending_proposal_params
|
||||
params.require(:spending_proposal).permit(:title, :description, :external_url, :geozone_id, :terms_of_service, :captcha, :captcha_key)
|
||||
end
|
||||
|
||||
def check_verified_user
|
||||
unless current_user.level_two_or_three_verified?
|
||||
redirect_to management_document_verifications_path, alert: t("management.spending_proposals.alert.unverified_user")
|
||||
def only_verified_users
|
||||
check_verified_user t("management.spending_proposals.alert.unverified_user")
|
||||
end
|
||||
|
||||
# This should not be necessary. Maybe we could create a specific show view for managers.
|
||||
def set_spending_proposal_votes(spending_proposals)
|
||||
@spending_proposal_votes = current_user ? current_user.spending_proposal_votes(spending_proposals) : {}
|
||||
end
|
||||
|
||||
def set_geozone_name
|
||||
if params[:geozone] == 'all'
|
||||
@geozone_name = t('geozones.none')
|
||||
else
|
||||
@geozone_name = Geozone.find(params[:geozone]).name
|
||||
end
|
||||
end
|
||||
|
||||
def current_user
|
||||
managed_user
|
||||
def apply_filters_and_search(target)
|
||||
target = params[:unfeasible].present? ? target.unfeasible : target.not_unfeasible
|
||||
if params[:geozone].present?
|
||||
target = target.by_geozone(params[:geozone])
|
||||
set_geozone_name
|
||||
end
|
||||
target = target.search(params[:search]) if params[:search].present?
|
||||
target
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -18,6 +18,12 @@ class Management::UsersController < Management::BaseController
|
||||
end
|
||||
end
|
||||
|
||||
def erase
|
||||
managed_user.erase(t("management.users.erased_by_manager", manager: current_manager['login'])) if current_manager.present?
|
||||
destroy_session
|
||||
redirect_to management_document_verifications_path, notice: t("management.users.erased_notice")
|
||||
end
|
||||
|
||||
def logout
|
||||
destroy_session
|
||||
redirect_to management_root_url, notice: t("management.sessions.signed_out_managed_user")
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
class SpendingProposalsController < ApplicationController
|
||||
include FeatureFlags
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
before_action :authenticate_user!, except: [:index]
|
||||
before_action :verify_access, only: [:show]
|
||||
before_filter -> { flash.now[:notice] = flash[:notice].html_safe if flash[:html_safe] && flash[:notice] }
|
||||
before_action -> { flash.now[:notice] = flash[:notice].html_safe if flash[:html_safe] && flash[:notice] }
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
feature_flag :spending_proposals
|
||||
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@spending_proposals = apply_filters_and_search(SpendingProposal).page(params[:page]).for_render
|
||||
set_spending_proposal_votes(@spending_proposals)
|
||||
end
|
||||
|
||||
def new
|
||||
@spending_proposal = SpendingProposal.new
|
||||
end
|
||||
|
||||
def show
|
||||
set_spending_proposal_votes(@spending_proposal)
|
||||
end
|
||||
|
||||
def create
|
||||
@spending_proposal = SpendingProposal.new(spending_proposal_params)
|
||||
@spending_proposal.author = current_user
|
||||
@@ -29,19 +36,38 @@ class SpendingProposalsController < ApplicationController
|
||||
end
|
||||
|
||||
def destroy
|
||||
spending_proposal = current_user.spending_proposals.find(params[:id])
|
||||
spending_proposal = SpendingProposal.find(params[:id])
|
||||
spending_proposal.destroy
|
||||
redirect_to user_path(current_user, filter: 'spending_proposals'), notice: t('flash.actions.destroy.spending_proposal')
|
||||
end
|
||||
|
||||
def vote
|
||||
@spending_proposal.register_vote(current_user, 'yes')
|
||||
set_spending_proposal_votes(@spending_proposal)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def spending_proposal_params
|
||||
params.require(:spending_proposal).permit(:title, :description, :external_url, :geozone_id, :association_name, :terms_of_service, :captcha, :captcha_key)
|
||||
end
|
||||
|
||||
def verify_access
|
||||
raise CanCan::AccessDenied unless current_user.try(:valuator?) || current_user.try(:administrator?) || @spending_proposal.author == current_user
|
||||
def set_geozone_name
|
||||
if params[:geozone] == 'all'
|
||||
@geozone_name = t('geozones.none')
|
||||
else
|
||||
@geozone_name = Geozone.find(params[:geozone]).name
|
||||
end
|
||||
end
|
||||
|
||||
def apply_filters_and_search(target)
|
||||
target = params[:unfeasible].present? ? target.unfeasible : target.not_unfeasible
|
||||
if params[:geozone].present?
|
||||
target = target.by_geozone(params[:geozone])
|
||||
set_geozone_name
|
||||
end
|
||||
target = target.search(params[:search]) if params[:search].present?
|
||||
target
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -41,9 +41,7 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
end
|
||||
|
||||
def save_user(user)
|
||||
@user.save ||
|
||||
@user.save_requiring_finish_signup ||
|
||||
@user.save_requiring_finish_signup_without_email
|
||||
@user.save || @user.save_requiring_finish_signup
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -9,8 +9,9 @@ class Valuation::SpendingProposalsController < Valuation::BaseController
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
@geozone_filters = geozone_filters
|
||||
if current_user.valuator?
|
||||
@spending_proposals = SpendingProposal.search(params_for_current_valuator, @current_filter).order(created_at: :desc).page(params[:page])
|
||||
@spending_proposals = SpendingProposal.scoped_filter(params_for_current_valuator, @current_filter).order(cached_votes_up: :desc).page(params[:page])
|
||||
else
|
||||
@spending_proposals = SpendingProposal.none.page(params[:page])
|
||||
end
|
||||
@@ -18,6 +19,11 @@ class Valuation::SpendingProposalsController < Valuation::BaseController
|
||||
|
||||
def valuate
|
||||
if valid_price_params? && @spending_proposal.update(valuation_params)
|
||||
|
||||
if @spending_proposal.unfeasible_email_pending?
|
||||
@spending_proposal.send_unfeasible_email
|
||||
end
|
||||
|
||||
redirect_to valuation_spending_proposal_path(@spending_proposal), notice: t('valuation.spending_proposals.notice.valuate')
|
||||
else
|
||||
render action: :edit
|
||||
@@ -26,6 +32,25 @@ class Valuation::SpendingProposalsController < Valuation::BaseController
|
||||
|
||||
private
|
||||
|
||||
def geozone_filters
|
||||
spending_proposals = SpendingProposal.by_valuator(current_user.valuator.try(:id)).valuation_open.all.to_a
|
||||
|
||||
[ { name: t('valuation.spending_proposals.index.geozone_filter_all'),
|
||||
id: nil,
|
||||
pending_count: spending_proposals.size
|
||||
},
|
||||
{ name: t('geozones.none'),
|
||||
id: 'all',
|
||||
pending_count: spending_proposals.count{|x| x.geozone_id.nil?}
|
||||
}
|
||||
] + Geozone.all.order(name: :asc).collect do |g|
|
||||
{ name: g.name,
|
||||
id: g.id,
|
||||
pending_count: spending_proposals.count{|x| x.geozone_id == g.id}
|
||||
}
|
||||
end.select{ |x| x[:pending_count] > 0 }
|
||||
end
|
||||
|
||||
def valuation_params
|
||||
params[:spending_proposal][:feasible] = nil if params[:spending_proposal][:feasible] == 'nil'
|
||||
|
||||
|
||||
30
app/helpers/embed_videos_helper.rb
Normal file
30
app/helpers/embed_videos_helper.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
module EmbedVideosHelper
|
||||
|
||||
def embedded_video_code
|
||||
link = @proposal.video_url
|
||||
if link.match(/vimeo.*/)
|
||||
server = "Vimeo"
|
||||
elsif link.match(/youtu*.*/)
|
||||
server = "YouTube"
|
||||
end
|
||||
|
||||
if server == "Vimeo"
|
||||
regExp = /vimeo.*(staffpicks\/|channels\/|videos\/|video\/|\/)([^#\&\?]*).*/
|
||||
src = "https://player.vimeo.com/video/"
|
||||
elsif server == "YouTube"
|
||||
regExp = /youtu.*(be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/
|
||||
src = "https://www.youtube.com/embed/"
|
||||
end
|
||||
|
||||
if regExp
|
||||
match = link.match(regExp)
|
||||
end
|
||||
|
||||
if match and match[2]
|
||||
'<iframe src="' + src + match[2] + '" frameborder="0" allowfullscreen></iframe>'
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -3,4 +3,14 @@ module SpendingProposalsHelper
|
||||
def spending_proposal_tags_select_options
|
||||
ActsAsTaggableOn::Tag.spending_proposal_tags.pluck(:name)
|
||||
end
|
||||
|
||||
def namespaced_spending_proposal_path(spending_proposal, options={})
|
||||
@namespace_spending_proposal_path ||= namespace
|
||||
case @namespace_spending_proposal_path
|
||||
when "management"
|
||||
management_spending_proposal_path(spending_proposal, options)
|
||||
else
|
||||
spending_proposal_path(spending_proposal, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -14,4 +14,10 @@ module StatsHelper
|
||||
content_tag :div, "", opt
|
||||
end
|
||||
|
||||
def spending_proposals_chart_tag(opt={})
|
||||
events = events.join(',') if events.is_a? Array
|
||||
opt[:data] ||= {}
|
||||
opt[:data][:graph] = admin_api_stats_path(spending_proposals: true)
|
||||
content_tag :div, "", opt
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,9 +2,9 @@ module ValuationHelper
|
||||
|
||||
def valuator_select_options(valuator=nil)
|
||||
if valuator.present?
|
||||
Valuator.where.not(id: valuator.id).order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }.prepend([valuator.name, 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
|
||||
Valuator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }
|
||||
Valuator.all.order("description ASC").order("users.email ASC").includes(:user).collect { |v| [ v.description_or_email, v.id ] }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ class Mailer < ApplicationMailer
|
||||
@comment = comment
|
||||
@commentable = comment.commentable
|
||||
with_user(@commentable.author) do
|
||||
mail(to: @commentable.author.email, subject: t('mailers.comment.subject', commentable: t("activerecord.models.#{@commentable.class.name.downcase}", count: 1).downcase)) if @commentable.present? && @commentable.author.present?
|
||||
mail(to: @commentable.author.email, subject: t('mailers.comment.subject', commentable: t("activerecord.models.#{@commentable.class.name.underscore}", count: 1).downcase)) if @commentable.present? && @commentable.author.present?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,6 +33,15 @@ class Mailer < ApplicationMailer
|
||||
end
|
||||
end
|
||||
|
||||
def unfeasible_spending_proposal(spending_proposal)
|
||||
@spending_proposal = spending_proposal
|
||||
@author = spending_proposal.author
|
||||
|
||||
with_user(@author) do
|
||||
mail(to: @author.email, subject: t('mailers.unfeasible_spending_proposal.subject', code: @spending_proposal.code))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def with_user(user, &block)
|
||||
|
||||
@@ -37,7 +37,7 @@ module Abilities
|
||||
|
||||
can :manage, Annotation
|
||||
|
||||
can [:read, :update], SpendingProposal
|
||||
can [:read, :update, :destroy], SpendingProposal
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,8 +43,8 @@ module Abilities
|
||||
if user.level_two_or_three_verified?
|
||||
can :vote, Proposal
|
||||
can :vote_featured, Proposal
|
||||
can :vote, SpendingProposal
|
||||
can :create, SpendingProposal
|
||||
can :destroy, SpendingProposal, author_id: user.id
|
||||
end
|
||||
|
||||
can :create, Annotation
|
||||
|
||||
@@ -2,8 +2,10 @@ class SpendingProposal < ActiveRecord::Base
|
||||
include Measurable
|
||||
include Sanitizable
|
||||
include Taggable
|
||||
include Searchable
|
||||
|
||||
apply_simple_captcha
|
||||
acts_as_votable
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
belongs_to :geozone
|
||||
@@ -24,12 +26,17 @@ class SpendingProposal < ActiveRecord::Base
|
||||
scope :managed, -> { valuation_open.where(valuation_assignments_count: 0).where("administrator_id IS NOT ?", nil) }
|
||||
scope :valuating, -> { valuation_open.where("valuation_assignments_count > 0 AND valuation_finished = ?", false) }
|
||||
scope :valuation_finished, -> { where(valuation_finished: true) }
|
||||
scope :feasible, -> { where(feasible: true) }
|
||||
scope :unfeasible, -> { where(feasible: false) }
|
||||
scope :not_unfeasible, -> { where("feasible IS ? OR feasible = ?", nil, true) }
|
||||
|
||||
scope :by_admin, -> (admin) { where(administrator_id: admin.presence) }
|
||||
scope :by_tag, -> (tag_name) { tagged_with(tag_name) }
|
||||
scope :by_valuator, -> (valuator) { where("valuation_assignments.valuator_id = ?", valuator.presence).joins(:valuation_assignments) }
|
||||
|
||||
scope :for_render, -> { includes(:geozone, administrator: :user, valuators: :user) }
|
||||
scope :for_render, -> { includes(:geozone) }
|
||||
|
||||
before_validation :set_responsible_name
|
||||
|
||||
def description
|
||||
super.try :html_safe
|
||||
@@ -39,14 +46,26 @@ class SpendingProposal < ActiveRecord::Base
|
||||
params.select{|x,_| %w{geozone_id administrator_id tag_name valuator_id}.include? x.to_s }
|
||||
end
|
||||
|
||||
def self.search(params, current_filter)
|
||||
def self.scoped_filter(params, current_filter)
|
||||
results = self
|
||||
results = results.by_geozone(params[:geozone_id]) if params[:geozone_id].present?
|
||||
results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present?
|
||||
results = results.by_tag(params[:tag_name]) if params[:tag_name].present?
|
||||
results = results.by_valuator(params[:valuator_id]) if params[:valuator_id].present?
|
||||
results = results.send(current_filter) if current_filter.present?
|
||||
results.for_render
|
||||
results.includes(:geozone, administrator: :user, valuators: :user)
|
||||
end
|
||||
|
||||
def searchable_values
|
||||
{ title => 'A',
|
||||
author.username => 'B',
|
||||
geozone.try(:name) => 'B',
|
||||
description => 'C'
|
||||
}
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
self.pg_search(terms)
|
||||
end
|
||||
|
||||
def self.by_geozone(geozone)
|
||||
@@ -68,4 +87,51 @@ class SpendingProposal < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def unfeasible_email_pending?
|
||||
unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished?
|
||||
end
|
||||
|
||||
def unfeasible?
|
||||
feasible == false
|
||||
end
|
||||
|
||||
def valuation_finished?
|
||||
valuation_finished
|
||||
end
|
||||
|
||||
def total_votes
|
||||
cached_votes_up + physical_votes
|
||||
end
|
||||
|
||||
def code
|
||||
"#{created_at.strftime('%Y')}-#{id}" + (administrator.present? ? "-A#{administrator.id}" : "")
|
||||
end
|
||||
|
||||
def send_unfeasible_email
|
||||
Mailer.unfeasible_spending_proposal(self).deliver_later
|
||||
update(unfeasible_email_sent_at: Time.now)
|
||||
end
|
||||
|
||||
def reason_for_not_being_votable_by(user)
|
||||
return :not_voting_allowed if Setting["feature.spending_proposal_features.voting_allowed"].blank?
|
||||
return :not_logged_in unless user
|
||||
return :not_verified unless user.can?(:vote, SpendingProposal)
|
||||
return :unfeasible if unfeasible?
|
||||
return :organization if user.organization?
|
||||
end
|
||||
|
||||
def votable_by?(user)
|
||||
reason_for_not_being_votable_by(user).blank?
|
||||
end
|
||||
|
||||
def register_vote(user, vote_value)
|
||||
if votable_by?(user)
|
||||
vote_by(voter: user, vote: vote_value)
|
||||
end
|
||||
end
|
||||
|
||||
def set_responsible_name
|
||||
self.responsible_name = author.try(:document_number) if author.try(:document_number).present?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ class User < ActiveRecord::Base
|
||||
belongs_to :geozone
|
||||
|
||||
validates :username, presence: true, if: :username_required?
|
||||
validates :username, uniqueness: true, if: :username_required?
|
||||
validates :username, uniqueness: { scope: :registering_with_oauth }, if: :username_required?
|
||||
validates :document_number, uniqueness: { scope: :document_type }, allow_nil: true
|
||||
|
||||
validate :validate_username_length
|
||||
@@ -83,6 +83,11 @@ class User < ActiveRecord::Base
|
||||
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
|
||||
end
|
||||
|
||||
def spending_proposal_votes(spending_proposals)
|
||||
voted = votes.for_spending_proposals(spending_proposals)
|
||||
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
|
||||
end
|
||||
|
||||
def comment_flags(comments)
|
||||
comment_flags = flags.for_comments(comments)
|
||||
comment_flags.each_with_object({}){ |f, h| h[f.flaggable_id] = true }
|
||||
@@ -149,6 +154,7 @@ class User < ActiveRecord::Base
|
||||
confirmed_phone: nil,
|
||||
unconfirmed_phone: nil
|
||||
)
|
||||
self.identities.destroy_all
|
||||
end
|
||||
|
||||
def erased?
|
||||
@@ -177,11 +183,11 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def username_required?
|
||||
!organization? && !erased? && !registering_with_oauth
|
||||
!organization? && !erased?
|
||||
end
|
||||
|
||||
def email_required?
|
||||
!erased? && !registering_with_oauth
|
||||
!erased?
|
||||
end
|
||||
|
||||
def has_official_email?
|
||||
@@ -210,12 +216,21 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def save_requiring_finish_signup
|
||||
self.update(registering_with_oauth: true)
|
||||
begin
|
||||
self.registering_with_oauth = true
|
||||
self.save(validate: false)
|
||||
# Devise puts unique constraints for the email the db, so we must detect & handle that
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
self.email = nil
|
||||
self.save(validate: false)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def save_requiring_finish_signup_without_email
|
||||
self.update(registering_with_oauth: true, email: nil)
|
||||
def ability
|
||||
@ability ||= Ability.new(self)
|
||||
end
|
||||
delegate :can?, :cannot?, to: :ability
|
||||
|
||||
private
|
||||
def clean_document_number
|
||||
|
||||
@@ -32,7 +32,7 @@ class Verification::Management::Document
|
||||
end
|
||||
|
||||
def under_sixteen?(response)
|
||||
16.years.ago < string_to_date(response.date_of_birth)
|
||||
16.years.ago.beginning_of_day < response.date_of_birth.beginning_of_day
|
||||
end
|
||||
|
||||
def verified?
|
||||
|
||||
@@ -31,6 +31,8 @@ class Verification::Residence
|
||||
user.update(document_number: document_number,
|
||||
document_type: document_type,
|
||||
geozone: self.geozone,
|
||||
date_of_birth: date_of_birth.to_datetime,
|
||||
gender: gender,
|
||||
residence_verified_at: Time.now)
|
||||
end
|
||||
|
||||
@@ -75,6 +77,10 @@ class Verification::Residence
|
||||
@census_api_response.district_code
|
||||
end
|
||||
|
||||
def gender
|
||||
@census_api_response.gender
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def call_census_api
|
||||
@@ -84,7 +90,7 @@ class Verification::Residence
|
||||
def residency_valid?
|
||||
@census_api_response.valid? &&
|
||||
@census_api_response.postal_code == postal_code &&
|
||||
@census_api_response.date_of_birth == date_to_string(date_of_birth)
|
||||
@census_api_response.date_of_birth == date_of_birth
|
||||
end
|
||||
|
||||
def clean_document_number
|
||||
|
||||
@@ -4,14 +4,9 @@ class Verification::Sms
|
||||
attr_accessor :user, :phone, :confirmation_code
|
||||
|
||||
validates_presence_of :phone
|
||||
validates :phone, length: { is: 9 }
|
||||
validate :spanish_phone
|
||||
validates :phone, format: { with: /\A[\d \+]+\z/ }
|
||||
validate :uniqness_phone
|
||||
|
||||
def spanish_phone
|
||||
errors.add(:phone, :invalid) unless phone.start_with?('6', '7')
|
||||
end
|
||||
|
||||
def uniqness_phone
|
||||
errors.add(:phone, :taken) if User.where(confirmed_phone: phone).any?
|
||||
end
|
||||
|
||||
10
app/views/admin/shared/_spending_proposal_search.html.erb
Normal file
10
app/views/admin/shared/_spending_proposal_search.html.erb
Normal file
@@ -0,0 +1,10 @@
|
||||
<%= form_for(SpendingProposal.new, url: url, as: :spending_proposal, method: :get) do |f| %>
|
||||
<div class="row">
|
||||
<div class="small-12 medium-6 column">
|
||||
<%= text_field_tag :search, "", placeholder: t("admin.shared.spending_proposal_search.placeholder") %>
|
||||
</div>
|
||||
<div class="form-inline small-12 medium-3 column end">
|
||||
<%= f.submit t("admin.shared.spending_proposal_search.button"), class: "button success expanded" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -2,43 +2,71 @@
|
||||
<span class="icon-angle-left"></span> <%= t("admin.spending_proposals.show.back") %>
|
||||
<% end %>
|
||||
|
||||
<%= render 'written_by_author' %>
|
||||
|
||||
<h2 id="form"><%= t("admin.spending_proposals.edit.classification") %></h2>
|
||||
|
||||
<%= form_for @spending_proposal,
|
||||
url: admin_spending_proposal_path(@spending_proposal) do |f| %>
|
||||
|
||||
<% SpendingProposal.filter_params(params).each do |filter_name, filter_value| %>
|
||||
<%= hidden_field_tag filter_name, filter_value %>
|
||||
<%= hidden_field_tag filter_name, filter_value %>
|
||||
<% end %>
|
||||
|
||||
<%= f.select(:administrator_id,
|
||||
@admins.collect{ |a| [a.name_and_email, a.id ] },
|
||||
{ include_blank: t("admin.spending_proposals.edit.undefined") },
|
||||
class: "small-12 medium-6") %>
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :title, maxlength: SpendingProposal.title_max_length %>
|
||||
</div>
|
||||
|
||||
<%= f.label :tag_list, t("admin.spending_proposals.edit.tags") %>
|
||||
<div class="tags">
|
||||
<% @tags.each do |tag| %>
|
||||
<a class="js-add-tag-link"><%= tag.name %></a>
|
||||
<% end %>
|
||||
<div class="ckeditor small-12 column">
|
||||
<%= f.cktext_area :description, maxlength: SpendingProposal.description_max_length, ckeditor: { language: I18n.locale } %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :external_url %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.select :geozone_id, geozone_select_options, include_blank: t("geozones.none") %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.text_field :association_name, placeholder: t("spending_proposals.form.association_name") %>
|
||||
</div>
|
||||
</div>
|
||||
<%= f.text_field :tag_list, value: @spending_proposal.tag_list.to_s,
|
||||
label: false,
|
||||
placeholder: t("admin.spending_proposals.edit.tags_placeholder"),
|
||||
class: 'js-tag-list' %>
|
||||
|
||||
<%= f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %>
|
||||
<h2 id="classification"><%= t("admin.spending_proposals.edit.classification") %></h2>
|
||||
|
||||
<%= f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %>
|
||||
<%= b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %>
|
||||
<% end %>
|
||||
<div class="row">
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.select(:administrator_id,
|
||||
@admins.collect{ |a| [a.name_and_email, a.id ] },
|
||||
{ include_blank: t("admin.spending_proposals.edit.undefined") }) %>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :tag_list, t("admin.spending_proposals.edit.tags") %>
|
||||
<div class="tags">
|
||||
<% @tags.each do |tag| %>
|
||||
<a class="js-add-tag-link"><%= tag.name %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= f.text_field :tag_list, value: @spending_proposal.tag_list.to_s,
|
||||
label: false,
|
||||
placeholder: t("admin.spending_proposals.edit.tags_placeholder"),
|
||||
class: 'js-tag-list' %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %>
|
||||
|
||||
<%= f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %>
|
||||
<%= b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="clear">
|
||||
<%= f.submit(class: "button", value: t("admin.spending_proposals.edit.submit_button")) %>
|
||||
</p>
|
||||
|
||||
<% end %>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -2,21 +2,30 @@
|
||||
|
||||
<div class="row margin">
|
||||
<%= form_tag admin_spending_proposals_path, method: :get, enforce_utf8: false do %>
|
||||
<div class="small-12 medium-4 column">
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= select_tag :administrator_id,
|
||||
options_for_select(admin_select_options, params[:administrator_id]),
|
||||
{ prompt: t("admin.spending_proposals.index.administrator_filter_all"),
|
||||
label: false,
|
||||
class: "js-submit-on-change" } %>
|
||||
</div>
|
||||
<div class="small-12 medium-4 column">
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= select_tag :valuator_id,
|
||||
options_for_select(valuator_select_options, params[:valuator_id]),
|
||||
{ prompt: t("admin.spending_proposals.index.valuator_filter_all"),
|
||||
label: false,
|
||||
class: "js-submit-on-change" } %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= select_tag :geozone_id,
|
||||
options_for_select(geozone_select_options.unshift([t("geozones.none"), "all"]), params[:geozone_id]),
|
||||
{ prompt: t("admin.spending_proposals.index.geozone_filter_all"),
|
||||
label: false,
|
||||
class: "js-submit-on-change" } %>
|
||||
</div>
|
||||
<div class="small-12 medium-4 column">
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= select_tag :tag_name,
|
||||
options_for_select(spending_proposal_tags_select_options, params[:tag_name]),
|
||||
{ prompt: t("admin.spending_proposals.index.tags_filter_all"),
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<%= link_to admin_spending_proposals_path(SpendingProposal.filter_params(params)) do %>
|
||||
<%= link_to admin_spending_proposals_path(SpendingProposal.filter_params(params)), data: {no_turbolink: true} do %>
|
||||
<span class="icon-angle-left"></span> <%= t("admin.spending_proposals.show.back") %>
|
||||
<% end %>
|
||||
|
||||
<%= render 'written_by_author' %>
|
||||
|
||||
<h2 id="classification"><%= t("admin.spending_proposals.show.classification") %></h2>
|
||||
<%= link_to t("admin.spending_proposals.show.edit"),
|
||||
edit_admin_spending_proposal_path(@spending_proposal,
|
||||
SpendingProposal.filter_params(params)) %>
|
||||
|
||||
<p>
|
||||
<%= link_to t("admin.spending_proposals.show.edit_classification"),
|
||||
edit_admin_spending_proposal_path(@spending_proposal,
|
||||
{anchor: 'form'}.merge(SpendingProposal.filter_params(params))) %>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<h2 id="classification"><%= t("admin.spending_proposals.show.classification") %></h2>
|
||||
|
||||
<p><strong><%= t("admin.spending_proposals.show.assigned_admin") %>:</strong>
|
||||
<%= @spending_proposal.administrator.try(:name_and_email) || t("admin.spending_proposals.show.undefined") %>
|
||||
@@ -31,12 +31,19 @@
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= link_to t("admin.spending_proposals.show.edit_classification"),
|
||||
edit_admin_spending_proposal_path(@spending_proposal,
|
||||
{anchor: 'classification'}.merge(SpendingProposal.filter_params(params))) %>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><%= t("admin.spending_proposals.show.dossier") %></h2>
|
||||
|
||||
<%= render 'valuation/spending_proposals/written_by_valuators' %>
|
||||
|
||||
<p>
|
||||
<%= link_to t("admin.spending_proposals.show.edit_dossier"), edit_valuation_spending_proposal_path(@spending_proposal) %>
|
||||
</p>
|
||||
|
||||
<%= render 'valuation/spending_proposals/written_by_valuators' %>
|
||||
|
||||
@@ -84,6 +84,13 @@
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<p class="featured">
|
||||
<%= t "admin.stats.show.summary.spending_proposals" %><br>
|
||||
<span class="number"><%= number_with_delimiter(@spending_proposals) %></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
@@ -97,6 +104,12 @@
|
||||
<%= events_chart_tag event %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<h2><%= t "admin.stats.show.spending_proposals_title" %></h2>
|
||||
<%= spending_proposals_chart_tag id: "spending_proposals" %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -54,8 +54,14 @@
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("debates.show.share") %></h3>
|
||||
<%= social_share_button_tag(@debate.title) %>
|
||||
</aside>
|
||||
<div class="social-share-full">
|
||||
<%= social_share_button_tag("#{@debate.title} #{setting['twitter_hashtag']}") %>
|
||||
<% if browser.device.mobile? %>
|
||||
<a href="whatsapp://send?text=<%= @debate.title %> <%= debate_url(@debate) %>" data-action="share/whatsapp/share">
|
||||
<span class="icon-whatsapp whatsapp"></span>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="subnavigation row expanded">
|
||||
<div class="subnavigation expanded">
|
||||
<div class="row">
|
||||
<div class="hide-for-small-only">
|
||||
<%= render "shared/subnavigation" %>
|
||||
|
||||
@@ -16,55 +16,65 @@
|
||||
|
||||
<body class="admin">
|
||||
<header>
|
||||
<div class="top-links">
|
||||
<section class="top-links">
|
||||
<div class="row">
|
||||
<%= render 'shared/locale_switcher' %>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="contain-to-grid clear">
|
||||
<nav class="top-bar" data-topbar>
|
||||
<ul class="title-area">
|
||||
<li class="name">
|
||||
<%= link_to management_root_path do %>
|
||||
<%= image_tag('header_logo_madrid.png', class: 'float-left', size: '96x96') %>
|
||||
<%= Setting['org_name'] %> <span>|</span> <span class="logo-site"><%= t("management.dashboard.index.title") %></span>
|
||||
<div class="row">
|
||||
<div class="top-bar">
|
||||
|
||||
<%= link_to Setting['org_name'], management_root_path, class: "logo show-for-small-only" %>
|
||||
|
||||
<span data-responsive-toggle="responsive-menu" data-hide-for="medium" class="float-right">
|
||||
<span class="menu-icon dark" data-toggle></span>
|
||||
<%= t("application.menu")%>
|
||||
</span>
|
||||
|
||||
<div id="responsive-menu">
|
||||
<div class="top-bar-title">
|
||||
<%= link_to management_root_path, class: "hide-for-small-only" do %>
|
||||
<%= image_tag('header_logo_madrid.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %>
|
||||
<%= Setting['org_name'] %>
|
||||
| <%= t("management.dashboard.index.title") %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li class="toggle-topbar menu-icon"><a href="#"><span></span></a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="row">
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= render "/management/menu" %>
|
||||
</div>
|
||||
<div class="row expanded">
|
||||
<main>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= render "/management/menu" %>
|
||||
</div>
|
||||
|
||||
<%= render "management/account_info" %>
|
||||
<%= render "management/account_info" %>
|
||||
|
||||
<div class="admin-content small-12 medium-9 column">
|
||||
<% if notice %>
|
||||
<div data-alert class="callout success" data-closable>
|
||||
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<%= notice %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="admin-content small-12 medium-9 column">
|
||||
<% if notice %>
|
||||
<div data-alert class="callout success" data-closable>
|
||||
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<%= notice %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if alert %>
|
||||
<div data-alert class="callout alert" data-closable>
|
||||
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<%= alert %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if alert %>
|
||||
<div data-alert class="callout alert" data-closable>
|
||||
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<%= alert %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= yield %>
|
||||
</div>
|
||||
<%= yield %>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
35
app/views/mailer/unfeasible_spending_proposal.html.erb
Normal file
35
app/views/mailer/unfeasible_spending_proposal.html.erb
Normal file
@@ -0,0 +1,35 @@
|
||||
<td style="padding-bottom: 20px; padding-left: 10px;">
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.hi") %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.unfeasible_html",
|
||||
title: @spending_proposal.title) %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px; padding-left: 12px; border-left: 2px solid #ccc;">
|
||||
<%= @spending_proposal.feasible_explanation %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.new_html",
|
||||
url: link_to(t("mailers.unfeasible_spending_proposal.new_href"),
|
||||
new_spending_proposal_url, style: "color: #2895F1; text-decoration: underline;")) %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.reconsider_html", code: @spending_proposal.code) %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.sorry") %>
|
||||
</p>
|
||||
|
||||
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.sincerely") %><br>
|
||||
<span style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 12px;font-weight: normal;line-height: 24px; color: #ccc;">
|
||||
<%= t("mailers.unfeasible_spending_proposal.signatory") %></span>
|
||||
</p>
|
||||
</td>
|
||||
@@ -1,5 +1,5 @@
|
||||
<% if managed_user.document_number.present? %>
|
||||
<section class="small-12 medium-9 column margin-top">
|
||||
<section class="small-12 medium-9 column">
|
||||
<div class="account-info">
|
||||
|
||||
<%= link_to(t("management.account_info.change_user"), logout_management_users_path, method: :delete, class: 'float-right change-user') %>
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "account" %>>
|
||||
<%= link_to management_account_path do %>
|
||||
<span class="icon-user"></span>
|
||||
<%= t("management.menu.edit_user_accounts") %>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "proposals" and action_name == "new" %>>
|
||||
<%= link_to new_management_proposal_path do %>
|
||||
<span class="icon-proposals"></span>
|
||||
@@ -34,11 +41,25 @@
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "spending_proposals" and action_name == "index" %>>
|
||||
<%= link_to management_spending_proposals_path do %>
|
||||
<span class="icon-like"></span>
|
||||
<%= t("management.menu.support_spending_proposals") %>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "proposals" and action_name == "print" %>>
|
||||
<%= link_to print_management_proposals_path do %>
|
||||
<span class="icon-print"></span>
|
||||
<%= t("management.menu.print_proposals") %>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "spending_proposals" and action_name == "print" %>>
|
||||
<%= link_to print_management_spending_proposals_path do %>
|
||||
<span class="icon-print"></span>
|
||||
<%= t("management.menu.print_spending_proposals") %>
|
||||
<% end %>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
3
app/views/management/account/show.html.erb
Normal file
3
app/views/management/account/show.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<h2><%= t("management.account.show.title") %></h2>
|
||||
|
||||
<%= render 'management/users/erase_user_account' %>
|
||||
@@ -1,14 +1,6 @@
|
||||
<div class="dashboard">
|
||||
<h2><%= t("management.dashboard.index.title") %></h2>
|
||||
|
||||
<p>Desde aquí puedes gestionar usuarios a través de las siguientes acciones:</p>
|
||||
|
||||
<h3>Usuarios</h3>
|
||||
|
||||
<h3>Crear propuesta</h3>
|
||||
|
||||
<h3>Apoyar propuesta</h3>
|
||||
|
||||
<h3>Imprimir propuestas</h3>
|
||||
<p><%= t("management.dashboard.index.info") %></p>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -13,3 +13,5 @@
|
||||
<%= f.hidden_field :document_number %>
|
||||
<%= f.submit t("management.document_verifications.verify"), class: "button success" %>
|
||||
<% end %>
|
||||
|
||||
<%= render 'management/users/erase_user_account' %>
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="filters">
|
||||
<div class="small-12 medium-7 float-left">
|
||||
<% if @search_terms %>
|
||||
<h2 class="margin-top">
|
||||
<h2>
|
||||
<%= page_entries_info @proposals %>
|
||||
<%= t("proposals.index.search_results", count: @proposals.size, search_term: @search_terms) %>
|
||||
</h2>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<%= render @proposals %>
|
||||
|
||||
<div class="for-print-only">
|
||||
<p><strong><%= t("management.print.info") %></strong><br>
|
||||
<%= t("management.print.note") %></p>
|
||||
<p><strong><%= t("management.print.proposals_info") %></strong><br>
|
||||
<%= t("management.print.proposals_note") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<%= render partial: 'spending_proposals/spending_proposal', locals: {spending_proposal: spending_proposal} %>
|
||||
2
app/views/management/spending_proposals/_votes.html.erb
Normal file
2
app/views/management/spending_proposals/_votes.html.erb
Normal file
@@ -0,0 +1,2 @@
|
||||
<%= render 'spending_proposals/votes',
|
||||
{ spending_proposal: spending_proposal, vote_url: vote_management_spending_proposal_path(spending_proposal, value: 'yes') } %>
|
||||
25
app/views/management/spending_proposals/index.html.erb
Normal file
25
app/views/management/spending_proposals/index.html.erb
Normal file
@@ -0,0 +1,25 @@
|
||||
<main>
|
||||
<span class="not-print">
|
||||
<%= render 'admin/shared/spending_proposal_search', url: management_spending_proposals_path %>
|
||||
</span>
|
||||
|
||||
<div class="wrap row">
|
||||
<div id="investment-projects" class="investment-projects-list small-12 medium-9 column">
|
||||
|
||||
|
||||
<div class="small-12 search-results">
|
||||
<%= content_tag(:h2, t("management.spending_proposals.filters.unfeasible")) if params[:unfeasible].present? %>
|
||||
<%= content_tag(:h2, t("management.spending_proposals.filters.by_geozone", geozone: @geozone_name)) if @geozone_name.present? %>
|
||||
<% if params[:search].present? %>
|
||||
<h2>
|
||||
<%= page_entries_info @spending_proposals %>
|
||||
<%= t("management.spending_proposals.search_results", count: @spending_proposals.size, search_term: params[:search]) %>
|
||||
</h2>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= render @spending_proposals %>
|
||||
<%= paginate @spending_proposals %>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
34
app/views/management/spending_proposals/print.html.erb
Normal file
34
app/views/management/spending_proposals/print.html.erb
Normal file
@@ -0,0 +1,34 @@
|
||||
<main>
|
||||
<div class="row">
|
||||
<div id="investment-projects" class="investment-projects-list small-12 column">
|
||||
|
||||
<div class="not-print">
|
||||
<%= form_tag print_management_spending_proposals_path, method: :get, enforce_utf8: false do %>
|
||||
<div class="small-12 medium-4 column float-left">
|
||||
<%= select_tag :geozone,
|
||||
options_for_select(geozone_select_options.unshift([t("geozones.none"), "all"]), params[:geozone]),
|
||||
{ label: false,
|
||||
class: "js-submit-on-change" } %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<a id="print_link" href="javascript:window.print();" class="button warning float-right">
|
||||
<%= t('management.spending_proposals.print.print_button') %>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="small-12 search-results">
|
||||
<%= content_tag(:h2, t("management.spending_proposals.filters.unfeasible"), class: "inline-block") if params[:unfeasible].present? %>
|
||||
<%= content_tag(:h2, t("management.spending_proposals.filters.by_geozone", geozone: @geozone_name), class: "inline-block") if @geozone_name.present? %>
|
||||
<%= content_tag(:h2, t("management.spending_proposals.search_results", count: @spending_proposals.size, search_term: params[:search]), class: "inline-block") if params[:search].present? %>
|
||||
</div>
|
||||
|
||||
<%= render @spending_proposals %>
|
||||
|
||||
<div class="for-print-only">
|
||||
<p><strong><%= t("management.print.spending_proposals_info") %></strong><br>
|
||||
<%= t("management.print.spending_proposals_note") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
1
app/views/management/spending_proposals/vote.js.erb
Normal file
1
app/views/management/spending_proposals/vote.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= render template: 'spending_proposals/vote' %>
|
||||
9
app/views/management/users/_erase_user_account.html.erb
Normal file
9
app/views/management/users/_erase_user_account.html.erb
Normal file
@@ -0,0 +1,9 @@
|
||||
<%= link_to t("management.users.erase_account_link"), "#", class: "delete js-toggle-link", data: { "toggle-selector" => "#erase-account-form" } %>
|
||||
|
||||
<div id="erase-account-form" style="display:none">
|
||||
<div class="callout alert medium-6">
|
||||
<%= t("management.users.erase_warning") %>
|
||||
</div>
|
||||
|
||||
<%= link_to t("management.users.erase_submit"), erase_management_users_path, method: :delete, class: "button alert", data: { confirm: t("management.users.erase_account_confirm") } %>
|
||||
</div>
|
||||
@@ -2,7 +2,6 @@
|
||||
<section class="row-full comments">
|
||||
<div class="row">
|
||||
<div id="comments" class="small-12 column">
|
||||
|
||||
<h2>
|
||||
<%= t("proposals.show.comments_title") %>
|
||||
<span class="js-comments-count">(<%= @proposal.comments_count %>)</span>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<% if voted_for?(@featured_proposals_votes, proposal) %>
|
||||
<% if setting['twitter_handle'] %>
|
||||
<div class="share-supported">
|
||||
<%= social_share_button_tag(proposal.title, url: proposal_url(proposal), via: setting['twitter_handle']) %>
|
||||
<%= social_share_button_tag("#{proposal.title} #{setting['twitter_hashtag']}", url: proposal_url(proposal), via: setting['twitter_handle']) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
<% if voted_for?(@proposal_votes, proposal) && setting['twitter_handle'] %>
|
||||
<div class="share-supported">
|
||||
<%= social_share_button_tag(proposal.title, url: proposal_url(proposal), via: setting['twitter_handle']) %>
|
||||
<%= social_share_button_tag("#{proposal.title} #{setting['twitter_hashtag']}", url: proposal_url(proposal), via: setting['twitter_handle']) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
|
||||
<blockquote><%= @proposal.summary %></blockquote>
|
||||
|
||||
<% if @proposal.video_url.present? %>
|
||||
<div class="small-12 medium-7 small-centered">
|
||||
<div class="flex-video">
|
||||
<div id="js-embedded-video" data-video-code="<%= embedded_video_code %>"></div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= safe_html_with_links @proposal.description %>
|
||||
|
||||
<% if @proposal.external_url.present? %>
|
||||
@@ -86,7 +94,14 @@
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("proposals.show.share") %></h3>
|
||||
<%= social_share_button_tag(@proposal.title) %>
|
||||
<div class="social-share-full">
|
||||
<%= social_share_button_tag("#{@proposal.title} #{setting['twitter_hashtag']}") %>
|
||||
<% if browser.device.mobile? %>
|
||||
<a href="whatsapp://send?text=<%= @proposal.title %> <%= proposal_url(@proposal) %>" data-action="share/whatsapp/share">
|
||||
<span class="icon-whatsapp whatsapp"></span>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<main>
|
||||
<div class="wrap row proposals-summary">
|
||||
<div id="proposals" class="proposals-list small-12 medium-9 column margin-top">
|
||||
<div id="proposals" class="proposals-list small-12 medium-9 column">
|
||||
|
||||
<%= link_to :back, class: 'back left' do %>
|
||||
<span class="icon-angle-left left"></span>
|
||||
|
||||
15
app/views/spending_proposals/_sidebar.html.erb
Normal file
15
app/views/spending_proposals/_sidebar.html.erb
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3 class="sidebar-title"><%= t("spending_proposals.index.sidebar.geozones") %></h3>
|
||||
<br>
|
||||
<div class="geozone">
|
||||
<%= link_to t('geozones.all'), spending_proposals_path(geozone: nil) %>
|
||||
<%= link_to t('geozones.none'), spending_proposals_path(geozone: 'all') %>
|
||||
<% Geozone.all.each do |geozone| %>
|
||||
<%= link_to geozone.name, spending_proposals_path(geozone: geozone.id) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3 class="sidebar-title"><%= t("spending_proposals.index.sidebar.feasibility") %></h3>
|
||||
<br>
|
||||
<%= link_to t('spending_proposals.index.sidebar.unfeasible'), spending_proposals_path(unfeasible: '1') %>
|
||||
59
app/views/spending_proposals/_spending_proposal.html.erb
Normal file
59
app/views/spending_proposals/_spending_proposal.html.erb
Normal file
@@ -0,0 +1,59 @@
|
||||
<div id="<%= dom_id(spending_proposal) %>" class="investment-project clear">
|
||||
<div class="panel">
|
||||
<div class="row">
|
||||
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="investment-project-content">
|
||||
|
||||
<% cache [locale_and_user_status(spending_proposal), 'index', spending_proposal, spending_proposal.author] do %>
|
||||
<span class="label-investment-project float-left"><%= t("spending_proposals.spending_proposal.spending_proposal") %></span>
|
||||
<span class="icon-budget"></span>
|
||||
<h3><%= link_to spending_proposal.title, namespaced_spending_proposal_path(spending_proposal) %></h3>
|
||||
<p class="investment-project-info">
|
||||
|
||||
<%= l spending_proposal.created_at.to_date %>
|
||||
|
||||
<% if spending_proposal.author.hidden? || spending_proposal.author.erased? %>
|
||||
<span class="bullet"> • </span>
|
||||
<span class="author">
|
||||
<%= t("spending_proposals.show.author_deleted") %>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="bullet"> • </span>
|
||||
<span class="author">
|
||||
<%= spending_proposal.author.name %>
|
||||
</span>
|
||||
<% if spending_proposal.author.official? %>
|
||||
<span class="bullet"> • </span>
|
||||
<span class="label round level-<%= spending_proposal.author.official_level %>">
|
||||
<%= spending_proposal.author.official_position %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if spending_proposal.author.verified_organization? %>
|
||||
<span class="bullet"> • </span>
|
||||
<span class="label round is-association">
|
||||
<%= t("shared.collective") %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<span class="bullet"> • </span>
|
||||
<%= geozone_name(spending_proposal) %>
|
||||
</p>
|
||||
<div class="investment-project-description">
|
||||
<p><%= link_to spending_proposal.description, namespaced_spending_proposal_path(spending_proposal) %></p>
|
||||
<div class="truncate"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="<%= dom_id(spending_proposal) %>_votes" class="small-12 medium-3 column text-center">
|
||||
<%= render 'votes',
|
||||
{ spending_proposal: spending_proposal, vote_url: vote_spending_proposal_path(spending_proposal, value: 'yes') } %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
42
app/views/spending_proposals/_votes.html.erb
Normal file
42
app/views/spending_proposals/_votes.html.erb
Normal file
@@ -0,0 +1,42 @@
|
||||
<div class="supports">
|
||||
|
||||
<% reason = spending_proposal.reason_for_not_being_votable_by(current_user) %>
|
||||
<% voting_allowed = true unless reason.presence == :not_voting_allowed %>
|
||||
<% user_voted_for = voted_for?(@spending_proposal_votes, spending_proposal) %>
|
||||
|
||||
<span class="total-supports <%= 'no-button' unless voting_allowed || user_voted_for %>">
|
||||
<%= t("spending_proposals.spending_proposal.supports", count: spending_proposal.total_votes) %>
|
||||
</span>
|
||||
|
||||
<div class="in-favor">
|
||||
<% if user_voted_for %>
|
||||
<div class="supported">
|
||||
<%= t("spending_proposals.spending_proposal.already_supported") %>
|
||||
</div>
|
||||
<% elsif voting_allowed %>
|
||||
<%= link_to vote_url,
|
||||
class: "button button-support small expanded",
|
||||
title: t('spending_proposals.spending_proposal.support_title'), method: "post", remote: true do %>
|
||||
<%= t("spending_proposals.spending_proposal.support") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if reason.present? && !user_voted_for %>
|
||||
<div class="no-supports-allowed" style='display:none'>
|
||||
<p>
|
||||
<%= t("votes.spending_proposals.#{reason}",
|
||||
verify_account: link_to(t("votes.verify_account"), verification_path),
|
||||
signin: link_to(t("votes.signin"), new_user_session_path),
|
||||
signup: link_to(t("votes.signup"), new_user_registration_path)
|
||||
).html_safe %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if user_voted_for && setting['twitter_handle'] %>
|
||||
<div class="share-supported">
|
||||
<%= social_share_button_tag("#{spending_proposal.title} #{setting['twitter_hashtag']}", url: spending_proposal_url(spending_proposal), via: setting['twitter_handle']) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -1,16 +1,37 @@
|
||||
<% provide :title do %><%= t('spending_proposals.index.title') %><% end %>
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="more-information text small-12 medium-8 column">
|
||||
<h1><%= t('spending_proposals.index.title') %></h1>
|
||||
<% content_for :header_addon do %>
|
||||
<%= render "shared/search_form",
|
||||
search_path: spending_proposals_path(page: 1),
|
||||
i18n_namespace: "spending_proposals.index.search_form" %>
|
||||
<% end %>
|
||||
|
||||
<p><%= t('spending_proposals.index.text_html') %></p>
|
||||
<main>
|
||||
<div class="wrap row">
|
||||
<div id="investment-projects" class="investment-projects-list small-12 medium-9 column">
|
||||
|
||||
<% if can? :create, SpendingProposal %>
|
||||
<%= link_to t('spending_proposals.index.create_link'), new_spending_proposal_path, class: 'button' %>
|
||||
<% else %>
|
||||
<p><%= t('spending_proposals.index.verified_only', verify_account: link_to(t('spending_proposals.index.verify_account'), verification_path)).html_safe %></p>
|
||||
<% end %>
|
||||
<div class="small-12 search-results">
|
||||
<%= content_tag(:h2, t("spending_proposals.index.unfeasible")) if params[:unfeasible].present? %>
|
||||
<%= content_tag(:h2, t("spending_proposals.index.by_geozone", geozone: @geozone_name)) if @geozone_name.present? %>
|
||||
<% if params[:search].present? %>
|
||||
<h2>
|
||||
<%= page_entries_info @spending_proposals %>
|
||||
<%= t("spending_proposals.index.search_results", count: @spending_proposals.size, search_term: params[:search]) %>
|
||||
</h2>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="show-for-small-only">
|
||||
<%= link_to t("spending_proposals.index.start_spending_proposal"), new_spending_proposal_path, class: 'button expanded' %>
|
||||
</div>
|
||||
<%= render partial: 'spending_proposals/spending_proposal', collection: @spending_proposals %>
|
||||
<%= paginate @spending_proposals %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside id="sidebar" class="margin-bottom">
|
||||
<%= render 'sidebar' %>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<% provide :title do %><%= @spending_proposal.title %><% end %>
|
||||
|
||||
<section class="proposal-show">
|
||||
<section class="investment-project-show">
|
||||
<div id="<%= dom_id(@spending_proposal) %>" class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
|
||||
<h1><%= @spending_proposal.title %></h1>
|
||||
|
||||
<div class="spending-proposal-info">
|
||||
<div class="investment-project-info">
|
||||
<%= render '/shared/author_info', resource: @spending_proposal %>
|
||||
|
||||
<span class="bullet"> • </span>
|
||||
@@ -15,6 +15,12 @@
|
||||
<%= geozone_name(@spending_proposal) %>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<p id="spending_proposal_code">
|
||||
<%= t("spending_proposals.show.code") %>
|
||||
<strong><%= @spending_proposal.id %></strong>
|
||||
</p>
|
||||
|
||||
<%= safe_html_with_links @spending_proposal.description.html_safe %>
|
||||
|
||||
<% if @spending_proposal.external_url.present? %>
|
||||
@@ -25,5 +31,26 @@
|
||||
|
||||
</div>
|
||||
|
||||
<aside class="small-12 medium-3 column">
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("votes.supports") %></h3>
|
||||
<div class="text-center">
|
||||
<div id="<%= dom_id(@spending_proposal) %>_votes">
|
||||
<%= render 'votes',
|
||||
{ spending_proposal: @spending_proposal, vote_url: vote_spending_proposal_path(@spending_proposal, value: 'yes') } %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("spending_proposals.show.share") %></h3>
|
||||
<div class="social-share-full">
|
||||
<%= social_share_button_tag("#{@spending_proposal.title} #{setting['twitter_hashtag']}") %>
|
||||
<% if browser.device.mobile? %>
|
||||
<a href="whatsapp://send?text=<%= @spending_proposal.title %> <%= spending_proposal_url(@spending_proposal) %>" data-action="share/whatsapp/share">
|
||||
<span class="icon-whatsapp whatsapp"></span>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
1
app/views/spending_proposals/vote.js.erb
Normal file
1
app/views/spending_proposals/vote.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#<%= dom_id(@spending_proposal) %>_votes").html('<%= j render("spending_proposals/votes", spending_proposal: @spending_proposal, vote_url: vote_spending_proposal_path(@spending_proposal, value: "yes")) %>');
|
||||
@@ -3,6 +3,10 @@
|
||||
<%= form_for current_user, as: :user, url: do_finish_signup_path, html: { role: 'form'} do |f| %>
|
||||
<%= render 'shared/errors', resource: current_user %>
|
||||
|
||||
<div class='callout primary'>
|
||||
<%= t("omniauth.finish_signup.username_warning") %>
|
||||
</div>
|
||||
|
||||
<% if current_user.errors.include? :username %>
|
||||
<%= f.text_field :username, placeholder: t("devise_views.users.registrations.new.username_label") %>
|
||||
<% else %>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<h2><%= t("valuation.spending_proposals.index.title") %></h2>
|
||||
|
||||
<div>
|
||||
<%= form_tag valuation_spending_proposals_path, method: :get, enforce_utf8: false do %>
|
||||
<div class="small-12 medium-4 column float-right">
|
||||
<%= select_tag :geozone_id,
|
||||
options_for_select(geozone_select_options.unshift([t("geozones.none"), "all"]), params[:geozone_id]),
|
||||
{ prompt: t("valuation.spending_proposals.index.geozone_filter_all"),
|
||||
label: false,
|
||||
class: "js-submit-on-change" } %>
|
||||
<div class="row collapse">
|
||||
<% @geozone_filters.each_slice(8) do |slice| %>
|
||||
<div class="small-12 medium-4 column select-geozone">
|
||||
<% slice.each do |filter| %>
|
||||
<%= link_to valuation_spending_proposals_path(geozone_id: filter[:id]),
|
||||
class: "#{'active' if params[:geozone_id].to_s == filter[:id].to_s}" do %>
|
||||
<%= filter[:name] %> (<%= filter[:pending_count] %>)
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -29,9 +29,10 @@
|
||||
<%= render "shared/errors", resource: @sms %>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<%= f.label t("verification.sms.new.phone") %>
|
||||
<%= f.label :phone, t("verification.sms.new.phone"), class: "inline-block" %>
|
||||
<span class="inline-block"><%= t("verification.sms.new.phone_format_html") %></span>
|
||||
<p class="note"><%= t("verification.sms.new.phone_note") %></p>
|
||||
<%= f.text_field :phone, label: false %>
|
||||
<%= f.text_field :phone, label: false, placeholder: t("verification.sms.new.phone_placeholder") %>
|
||||
</div>
|
||||
|
||||
<%= f.submit t("verification.sms.new.submit_button"), class: "button success" %>
|
||||
|
||||
@@ -131,6 +131,7 @@ ignore_unused:
|
||||
- 'proposals.index.select_order'
|
||||
- 'proposals.index.orders.*'
|
||||
- 'proposals.index.search_form.*'
|
||||
- 'spending_proposals.index.search_form.*'
|
||||
- 'notifications.index.comments_on*'
|
||||
- 'notifications.index.replies_to*'
|
||||
- 'helpers.page_entries_info.*' # kaminari
|
||||
|
||||
@@ -7,6 +7,10 @@ ActsAsVotable::Vote.class_eval do
|
||||
where(votable_type: 'Proposal', votable_id: proposals)
|
||||
end
|
||||
|
||||
def self.for_spending_proposals(spending_proposals)
|
||||
where(votable_type: 'SpendingProposal', votable_id: spending_proposals)
|
||||
end
|
||||
|
||||
def value
|
||||
vote_flag
|
||||
end
|
||||
|
||||
@@ -67,6 +67,13 @@ en:
|
||||
organization:
|
||||
name: "Name of organisation"
|
||||
responsible_name: "Person responsible for the group"
|
||||
spending_proposal:
|
||||
administrator_id: "Administrador"
|
||||
association_name: "Association name"
|
||||
description: "Description"
|
||||
external_url: "Link to additional documentation"
|
||||
geozone_id: "Scope of operation"
|
||||
title: "Title"
|
||||
errors:
|
||||
models:
|
||||
debate:
|
||||
@@ -77,5 +84,3 @@ en:
|
||||
attributes:
|
||||
tag_list:
|
||||
less_than_or_equal_to: "tags must be less than or equal to %{count}"
|
||||
spending_proposal:
|
||||
administrator_id: "Administrator"
|
||||
|
||||
@@ -38,8 +38,8 @@ es:
|
||||
one: "Propuesta ciudadana"
|
||||
other: "Propuestas ciudadanas"
|
||||
spending_proposal:
|
||||
one: "Propuesta de gasto"
|
||||
other: "Propuestas de gasto"
|
||||
one: "Propuesta de inversión"
|
||||
other: "Propuestas de inversión"
|
||||
attributes:
|
||||
comment:
|
||||
body: "Comentario"
|
||||
@@ -69,6 +69,11 @@ es:
|
||||
responsible_name: "Persona responsable del colectivo"
|
||||
spending_proposal:
|
||||
administrator_id: "Administrador"
|
||||
association_name: "Nombre de la asociación"
|
||||
description: "Descripción"
|
||||
external_url: "Enlace a documentación adicional"
|
||||
geozone_id: "Ámbito de actuación"
|
||||
title: "Título"
|
||||
errors:
|
||||
models:
|
||||
debate:
|
||||
|
||||
@@ -145,6 +145,9 @@ en:
|
||||
proposal_search:
|
||||
button: Search
|
||||
placeholder: Search proposals by title, code, description or question
|
||||
spending_proposal_search:
|
||||
button: Search
|
||||
placeholder: Search spending proposals by title or description
|
||||
user_search:
|
||||
button: Search
|
||||
placeholder: Search user by name or email'
|
||||
@@ -152,6 +155,7 @@ en:
|
||||
index:
|
||||
geozone_filter_all: All zones
|
||||
administrator_filter_all: All administrators
|
||||
valuator_filter_all: All valuators
|
||||
tags_filter_all: All tags
|
||||
filters:
|
||||
valuation_open: Open
|
||||
@@ -169,6 +173,7 @@ en:
|
||||
back: Back
|
||||
classification: Clasification
|
||||
heading: "Investment project %{id}"
|
||||
edit: Edit
|
||||
edit_classification: Edit classification
|
||||
association_name: Association
|
||||
by: By
|
||||
@@ -195,6 +200,7 @@ en:
|
||||
debates: Debates
|
||||
proposal_votes: Proposal votes
|
||||
proposals: Proposals
|
||||
spending_proposals: Spending Proposals
|
||||
unverified_users: Unverified users
|
||||
user_level_three: Level three users
|
||||
user_level_two: Level two users
|
||||
@@ -203,6 +209,7 @@ en:
|
||||
verified_users_who_didnt_vote_proposals: Verified users who didn't votes proposals
|
||||
visits: Visits
|
||||
votes: Total votes
|
||||
spending_proposals_title: Spending Proposals
|
||||
visits_title: Visits
|
||||
tags:
|
||||
create: Create Topic
|
||||
|
||||
@@ -145,6 +145,9 @@ es:
|
||||
proposal_search:
|
||||
button: Buscar
|
||||
placeholder: Buscar propuestas por título, código, descripción o pregunta
|
||||
spending_proposal_search:
|
||||
button: Buscar
|
||||
placeholder: Buscar propuestas por título o descripción
|
||||
user_search:
|
||||
button: Buscar
|
||||
placeholder: Buscar usuario por nombre o email
|
||||
@@ -152,6 +155,7 @@ es:
|
||||
index:
|
||||
geozone_filter_all: Todos los ámbitos de actuación
|
||||
administrator_filter_all: Todos los administradores
|
||||
valuator_filter_all: Todos los evaluadores
|
||||
tags_filter_all: Todas las etiquetas
|
||||
filters:
|
||||
valuation_open: Abiertas
|
||||
@@ -169,6 +173,7 @@ es:
|
||||
back: Volver
|
||||
classification: Clasificación
|
||||
heading: Propuesta de inversión %{id}
|
||||
edit: Editar
|
||||
edit_classification: Editar clasificación
|
||||
association_name: Asociación
|
||||
by: Autor
|
||||
@@ -195,6 +200,7 @@ es:
|
||||
debates: Debates
|
||||
proposal_votes: Votos en propuestas
|
||||
proposals: Propuestas
|
||||
spending_proposals: Propuestas de inversión
|
||||
unverified_users: Usuarios sin verificar
|
||||
user_level_three: Usuarios de nivel tres
|
||||
user_level_two: Usuarios de nivel dos
|
||||
@@ -203,6 +209,7 @@ es:
|
||||
verified_users_who_didnt_vote_proposals: Usuarios verificados que no han votado propuestas
|
||||
visits: Visitas
|
||||
votes: Votos
|
||||
spending_proposals_title: Propuestas de inversión
|
||||
visits_title: Visitas
|
||||
tags:
|
||||
create: Crear Tema
|
||||
|
||||
@@ -154,6 +154,7 @@ en:
|
||||
verification/sms: phone
|
||||
geozones:
|
||||
none: All city
|
||||
all: All scopes
|
||||
layouts:
|
||||
application:
|
||||
chrome: Google Chrome
|
||||
@@ -412,20 +413,43 @@ en:
|
||||
new: Create
|
||||
title: Spending proposal title
|
||||
index:
|
||||
create_link: Create spending proposal
|
||||
text_html: Here you can send spending proposals to be considered in the frame of the annual participatory budgeting.
|
||||
title: Participatory budgeting
|
||||
verified_only: Only verified users can create spending proposals, %{verify_account}.
|
||||
verify_account: verify your account
|
||||
unfeasible: Unfeasible investment projects
|
||||
by_geozone: "Investment projects with scope: %{geozone}"
|
||||
search_form:
|
||||
button: Search
|
||||
placeholder: Investment projects...
|
||||
title: Search
|
||||
search_results:
|
||||
one: " containing the term '%{search_term}'"
|
||||
other: " containing the term '%{search_term}'"
|
||||
sidebar:
|
||||
geozones: Scope of operation
|
||||
feasibility: Feasibility
|
||||
unfeasible: Unfeasible
|
||||
start_spending_proposal: Create an investment project
|
||||
new:
|
||||
back_link: Back
|
||||
more_info: How do participatory budgeting works?
|
||||
recommendation_one: It's mandatory that the proposal makes reference to a budgetable action.
|
||||
recommendation_three: Try to go into details when describing your spending proposal so the reviewing team undertands your points.
|
||||
recommendation_two: Any proposal or comment suggesting illegal action will be deleted.
|
||||
recommendations_title: How to create a spending proposal
|
||||
start_new: Create spending proposal
|
||||
back_link: Back
|
||||
show:
|
||||
author_deleted: User deleted
|
||||
code: 'Proposal code:'
|
||||
share: Share
|
||||
wrong_price_format: Only integer numbers
|
||||
spending_proposal:
|
||||
spending_proposal: Investment project
|
||||
already_supported: You have already supported this. Share it!
|
||||
support: Support
|
||||
support_title: Support this project
|
||||
supports:
|
||||
one: 1 support
|
||||
other: "%{count} supports"
|
||||
zero: No supports
|
||||
stats:
|
||||
index:
|
||||
visits: Visits
|
||||
@@ -476,6 +500,12 @@ en:
|
||||
unauthenticated: You must %{signin} or %{signup} to continue.
|
||||
verified_only: Only verified users can vote on proposals; %{verify_account}.
|
||||
verify_account: verify your account
|
||||
spending_proposals:
|
||||
not_logged_in: You must %{signin} or %{signup} to continue.
|
||||
not_verified: Only verified users can vote on proposals; %{verify_account}.
|
||||
organization: Organisations are not permitted to vote
|
||||
unfeasible: Unfeasible investment projects can not be supported
|
||||
not_voting_allowed: Voting phase is closed
|
||||
welcome:
|
||||
debates:
|
||||
alt: Icon debates
|
||||
@@ -512,6 +542,7 @@ en:
|
||||
omniauth:
|
||||
finish_signup:
|
||||
title: "Additional details"
|
||||
username_warning: "Due to a change in the way we interact with social networks, it is possible that your username now appears as 'already in use'. If that is your case, please choose a different username."
|
||||
twitter:
|
||||
sign_in: "Sign in with Twitter"
|
||||
sign_up: "Sign up with Twitter"
|
||||
|
||||
@@ -154,6 +154,7 @@ es:
|
||||
verification/sms: el teléfono
|
||||
geozones:
|
||||
none: Toda la ciudad
|
||||
all: Todos los ámbitos
|
||||
layouts:
|
||||
application:
|
||||
chrome: Google Chrome
|
||||
@@ -412,20 +413,43 @@ es:
|
||||
new: Crear
|
||||
title: Título de la propuesta de gasto
|
||||
index:
|
||||
create_link: Enviar propuesta de gasto
|
||||
text_html: Desde esta sección podrás sugerir propuestas de gasto que irán asociadas a las partidas de presupuestos ciudadanos.<br>El requisito principal es que sean propuestas presupuestables.
|
||||
title: Presupuestos participativos
|
||||
verified_only: Sólo los usuarios verificados pueden crear propuestas de gasto, %{verify_account}.
|
||||
verify_account: verifica tu cuenta
|
||||
unfeasible: Propuestas de inversión no viables
|
||||
by_geozone: "Propuestas de inversión con ámbito: %{geozone}"
|
||||
search_form:
|
||||
button: Buscar
|
||||
placeholder: Propuestas de inversión...
|
||||
title: Buscar
|
||||
search_results:
|
||||
one: " que contiene '%{search_term}'"
|
||||
other: " que contienen '%{search_term}'"
|
||||
sidebar:
|
||||
geozones: Ámbitos de actuación
|
||||
feasibility: Viabilidad
|
||||
unfeasible: No viables
|
||||
start_spending_proposal: Crea una propuesta de inversión
|
||||
new:
|
||||
back_link: Volver
|
||||
more_info: "¿Cómo funcionan los presupuestos participativos?"
|
||||
recommendation_one: Es fundamental que haga referencia a una actuación presupuestable.
|
||||
recommendation_three: Intenta detallar lo máximo posible la propuesta para que el equipo de gobierno encargado de estudiarla tenga las menor dudas posibles.
|
||||
recommendation_two: Cualquier propuesta o comentario que implique acciones ilegales será eliminada.
|
||||
recommendations_title: Cómo crear una propuesta de gasto
|
||||
start_new: Crear una propuesta de gasto
|
||||
back_link: Volver
|
||||
show:
|
||||
author_deleted: Usuario eliminado
|
||||
code: 'Código de la propuesta:'
|
||||
share: Compartir
|
||||
wrong_price_format: Solo puede incluir caracteres numéricos
|
||||
spending_proposal:
|
||||
spending_proposal: Propuesta de inversión
|
||||
already_supported: Ya has apoyado este proyecto. ¡Compártelo!
|
||||
support: Apoyar
|
||||
support_title: Apoyar este proyecto
|
||||
supports:
|
||||
one: 1 apoyo
|
||||
other: "%{count} apoyos"
|
||||
zero: Sin apoyos
|
||||
stats:
|
||||
index:
|
||||
visits: Visitas
|
||||
@@ -476,6 +500,12 @@ es:
|
||||
unauthenticated: Necesitas %{signin} o %{signup} para continuar.
|
||||
verified_only: Las propuestas sólo pueden ser votadas por usuarios verificados, %{verify_account}.
|
||||
verify_account: verifica tu cuenta
|
||||
spending_proposals:
|
||||
not_logged_in: Necesitas %{signin} o %{signup} para continuar.
|
||||
not_verified: Las propuestas de inversión sólo pueden ser apoyadas por usuarios verificados, %{verify_account}.
|
||||
organization: Las organizaciones no pueden votar.
|
||||
unfeasible: No se pueden votar propuestas inviables.
|
||||
not_voting_allowed: El periodo de votación está cerrado.
|
||||
welcome:
|
||||
debates:
|
||||
alt: Icono debates
|
||||
@@ -512,6 +542,7 @@ es:
|
||||
omniauth:
|
||||
finish_signup:
|
||||
title: "Detalles adicionales de tu cuenta"
|
||||
username_warning: "Debido a que hemos cambiado la forma en la que nos conectamos con redes sociales y es posible que tu nombre de usuario aparezca como 'ya en uso', incluso si antes podías acceder con él. Si es tu caso, por favor elige un nombre de usuario distinto."
|
||||
twitter:
|
||||
sign_in: "Entra con Twitter"
|
||||
sign_up: "Regístrate con Twitter"
|
||||
|
||||
@@ -20,3 +20,13 @@ en:
|
||||
new_reply_by_html: There is a new response from <b>%{commenter}</b> to your comment on
|
||||
subject: Someone has responded to your comment
|
||||
title: New response to your comment
|
||||
unfeasible_spending_proposal:
|
||||
hi: "Dear user,"
|
||||
new_html: "For all these, we invite you to elaborate a <strong>new proposal</strong> that ajusts to the conditions of this process. You can do it following this link: %{url}."
|
||||
new_href: "new investment project"
|
||||
reconsider_html: "If you believe that the rejected proposal meets the requirements to be an investment proposal, you can communicate this, within 48 hours, responding to the email address preparticipativos@madrid.es. Including the code %{code} in the subject of the email."
|
||||
sincerely: "Sincerely"
|
||||
signatory: "DEPARTMENT OF PUBLIC PARTICIPATION"
|
||||
sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation."
|
||||
subject: "Your investment project '%{code}' has been marked as unfeasible"
|
||||
unfeasible_html: "From the Madrid City Council we want to thank you for your participation in the <strong>participatory budgets of the city of Madrid</strong>. We regret to inform you that your proposal <strong>'%{title}'</strong> will be excluded from this participatory process for the following reason:"
|
||||
@@ -20,3 +20,13 @@ es:
|
||||
new_reply_by_html: Hay una nueva respuesta de <b>%{commenter}</b> a tu comentario en
|
||||
subject: Alguien ha respondido a tu comentario
|
||||
title: Nueva respuesta a tu comentario
|
||||
unfeasible_spending_proposal:
|
||||
hi: "Estimado usuario,"
|
||||
new_html: "Por todo ello, te invitamos a que elabores una <strong>nueva propuesta</strong> que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}."
|
||||
new_href: "nueva propuesta de inversión"
|
||||
reconsider_html: "Si consideras que la propuesta rechazada cumple los requisitos para mantenerla como propuesta de inversión, podrás comunicarlo, en el plazo de 48 horas, al correo preparticipativos@madrid.es, indicando necesariamente para su tramitación el código %{code} como asunto del correo, correspondiente a tu propuesta."
|
||||
sincerely: "Atentamente"
|
||||
signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA"
|
||||
sorry: "Sentimos las molestias ocasionadas y volvemos a darte las gracias por tu inestimable participación."
|
||||
subject: "Tu propuesta de inversión '%{code}' ha sido marcada como inviable"
|
||||
unfeasible_html: "Desde el Ayuntamiento de Madrid queremos agradecer tu participación en los <strong>Presupuestos Participativos de la ciudad de Madrid</strong>. Lamentamos informarte de que tu propuesta <strong>'%{title}'</strong> quedará excluida de este proceso participativo por el siguiente motivo:"
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
---
|
||||
en:
|
||||
management:
|
||||
account:
|
||||
alert:
|
||||
unverified_user: No verified user logged in yet
|
||||
show:
|
||||
title: User account
|
||||
account_info:
|
||||
change_user: Change user
|
||||
document_number_label: 'Document number:'
|
||||
@@ -12,6 +17,7 @@ en:
|
||||
dashboard:
|
||||
index:
|
||||
title: Management
|
||||
info: Here you can manage users through all actions listed in the left menu.
|
||||
document_number: Document number
|
||||
document_type_label: Document type
|
||||
document_verifications:
|
||||
@@ -41,17 +47,22 @@ en:
|
||||
print_proposals: Print proposals
|
||||
support_proposals: Support proposals
|
||||
create_spending_proposal: Create spending proposal
|
||||
print_spending_proposals: Print spending proposals
|
||||
support_spending_proposals: Support spending proposals
|
||||
title: Management
|
||||
users: Users
|
||||
edit_user_accounts: Edit user account
|
||||
permissions:
|
||||
create_proposals: Create proposals
|
||||
debates: Engage in debates
|
||||
support_proposals: Support proposals
|
||||
vote_proposals: Vote proposals
|
||||
print:
|
||||
info: Create yor proposal on http://decide.madrid.es
|
||||
note: The proposals more supported will be voted. If are accepted by a majority, the city Council shall be carried out.
|
||||
proposals_info: Create yor proposal on http://decide.madrid.es
|
||||
proposals_note: The proposals more supported will be voted. If are accepted by a majority, the city Council shall be carried out.
|
||||
proposals_title: 'Proposals:'
|
||||
spending_proposals_info: Participate at http://decide.madrid.es
|
||||
spending_proposals_note: Participatory budget will be assigned to the most votes spending proposals.
|
||||
print_info: Print this info
|
||||
proposals:
|
||||
alert:
|
||||
@@ -63,6 +74,14 @@ en:
|
||||
alert:
|
||||
unverified_user: User is not verified
|
||||
create: Create spending proposal
|
||||
filters:
|
||||
unfeasible: Unfeasible investment projects
|
||||
by_geozone: "Investment projects with scope: %{geozone}"
|
||||
print:
|
||||
print_button: Print
|
||||
search_results:
|
||||
one: " containing the term '%{search_term}'"
|
||||
other: " containing the term '%{search_term}'"
|
||||
sessions:
|
||||
signed_out: Signed out successfully.
|
||||
signed_out_managed_user: User session signed out successfully.
|
||||
@@ -72,3 +91,9 @@ en:
|
||||
create_user_info: 'We will create an account with the following data:'
|
||||
create_user_submit: Create user
|
||||
create_user_success_html: We have sent an email to the email address <b>%{email}</b> in order to verify that it belongs to this user. It contains a link they have to click. Then they will have to set their access password before being able to log in to the website
|
||||
erased_notice: User account deleted.
|
||||
erased_by_manager: "Deleted by manager: %{manager}"
|
||||
erase_account_link: Delete user
|
||||
erase_account_confirm: Are you sure you want to erase the account? This action can not be undone
|
||||
erase_warning: This action can not be undone. Please make sure you want to erase this account.
|
||||
erase_submit: Delete account
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
---
|
||||
es:
|
||||
management:
|
||||
account:
|
||||
alert:
|
||||
unverified_user: Solo se pueden editar cuentas de usuarios verificados
|
||||
show:
|
||||
title: Cuenta de usuario
|
||||
account_info:
|
||||
change_user: Cambiar usuario
|
||||
document_number_label: 'Número de documento:'
|
||||
@@ -12,6 +17,7 @@ es:
|
||||
dashboard:
|
||||
index:
|
||||
title: Gestión
|
||||
info: Desde aquí puedes gestionar usuarios a través de las acciones listadas en el menú de la izquierda.
|
||||
document_number: Número de documento
|
||||
document_type_label: Tipo de documento
|
||||
document_verifications:
|
||||
@@ -40,18 +46,23 @@ es:
|
||||
create_proposal: Crear propuesta
|
||||
print_proposals: Imprimir propuestas
|
||||
support_proposals: Apoyar propuestas
|
||||
create_spending_proposal: Crear propuesta de gasto
|
||||
create_spending_proposal: Crear propuesta de inversión
|
||||
print_spending_proposals: Imprimir propts. de inversión
|
||||
support_spending_proposals: Apoyar propts. de inversión
|
||||
title: Gestión
|
||||
users: Usuarios
|
||||
edit_user_accounts: Editar cuenta de usuario
|
||||
permissions:
|
||||
create_proposals: Crear nuevas propuestas
|
||||
debates: Participar en debates
|
||||
support_proposals: Apoyar propuestas
|
||||
vote_proposals: Participar en las votaciones finales
|
||||
print:
|
||||
info: Haz tu propuesta en http://decide.madrid.es
|
||||
note: Las propuestas más apoyadas serán llevadas a votación. Y si las acepta una mayoría, el Ayuntamiento las llevará a cabo.
|
||||
proposals_info: Haz tu propuesta en http://decide.madrid.es
|
||||
proposals_note: Las propuestas más apoyadas serán llevadas a votación. Y si las acepta una mayoría, el Ayuntamiento las llevará a cabo.
|
||||
proposals_title: 'Propuestas:'
|
||||
spending_proposals_info: Participa en http://decide.madrid.es
|
||||
spending_proposals_note: Los presupuestos participativos se invertirán en las propuestas de inversión más apoyadas.
|
||||
print_info: Imprimir esta información
|
||||
proposals:
|
||||
alert:
|
||||
@@ -62,7 +73,15 @@ es:
|
||||
spending_proposals:
|
||||
alert:
|
||||
unverified_user: Este usuario no está verificado
|
||||
create: Crear propuesta de gasto
|
||||
create: Crear propuesta de inversión
|
||||
filters:
|
||||
unfeasible: Propuestas de inversión no viables
|
||||
by_geozone: "Propuestas de inversión con ámbito: %{geozone}"
|
||||
print:
|
||||
print_button: Imprimir
|
||||
search_results:
|
||||
one: " que contiene '%{search_term}'"
|
||||
other: " que contienen '%{search_term}'"
|
||||
sessions:
|
||||
signed_out: Has cerrado la sesión correctamente.
|
||||
signed_out_managed_user: Se ha cerrado correctamente la sesión del usuario.
|
||||
@@ -72,3 +91,9 @@ es:
|
||||
create_user_info: 'Procedemos a crear un usuario con la siguiente información:'
|
||||
create_user_submit: Crear usuario
|
||||
create_user_success_html: Hemos enviado un correo electrónico a <b>%{email}</b> para verificar que es suya. El correo enviado contiene un link que el usuario deberá pulsar. Entonces podrá seleccionar una clave de acceso, y entrar en la web de participación.
|
||||
erased_notice: Cuenta de usuario borrada.
|
||||
erased_by_manager: "Borrada por el manager: %{manager}"
|
||||
erase_account_link: Borrar cuenta
|
||||
erase_account_confirm: ¿Seguro que quieres borrar a este usuario? Esta acción no se puede deshacer
|
||||
erase_warning: Esta acción no se puede deshacer. Por favor asegurese de que quiere eliminar esta cuenta.
|
||||
erase_submit: Borrar cuenta
|
||||
|
||||
@@ -15,4 +15,6 @@ en:
|
||||
per_page_code: "Code to be included on every page"
|
||||
feature:
|
||||
debates: Debates
|
||||
spending_proposals: Spending proposals
|
||||
spending_proposals: Investment projects
|
||||
spending_proposal_features:
|
||||
voting_allowed: Voting on investment projects
|
||||
|
||||
@@ -15,4 +15,6 @@ es:
|
||||
per_page_code: "Código a incluir en cada página"
|
||||
feature:
|
||||
debates: Debates
|
||||
spending_proposals: Propuestas de gasto
|
||||
spending_proposals: Propuestas de inversión
|
||||
spending_proposal_features:
|
||||
voting_allowed: Votaciones sobre propuestas de inversión.
|
||||
@@ -83,7 +83,9 @@ en:
|
||||
title: Security code confirmation
|
||||
new:
|
||||
phone: Enter your mobile phone number to receive the code
|
||||
phone_format_html: "<strong><em>(Example: 612345678 or +34612345678)</em></strong>"
|
||||
phone_note: We only user your phone for send to you a code, we never contact to you.
|
||||
phone_placeholder: "Example: 612345678 or +34612345678"
|
||||
submit_button: Send
|
||||
title: Send confirmation code
|
||||
update:
|
||||
|
||||
@@ -83,7 +83,9 @@ es:
|
||||
title: SMS de confirmación
|
||||
new:
|
||||
phone: Introduce tu teléfono móvil para recibir el código
|
||||
phone_format_html: "<strong><em>(Ejemplo: 612345678 ó +34612345678)</em></strong>"
|
||||
phone_note: Sólo usaremos tu teléfono para enviarte un código, nunca te contactaremos.
|
||||
phone_placeholder: "Ejemplo: 612345678 ó +34612345678"
|
||||
submit_button: Enviar
|
||||
title: SMS de confirmación
|
||||
update:
|
||||
|
||||
@@ -66,7 +66,9 @@ Rails.application.routes.draw do
|
||||
end
|
||||
|
||||
scope '/participatory_budget' do
|
||||
resources :spending_proposals, only: [:index, :new, :create, :show, :destroy], path: 'investment_projects'
|
||||
resources :spending_proposals, only: [:index, :new, :create, :show, :destroy], path: 'investment_projects' do
|
||||
post :vote, on: :member
|
||||
end
|
||||
end
|
||||
|
||||
resources :stats, only: [:index]
|
||||
@@ -74,19 +76,17 @@ Rails.application.routes.draw do
|
||||
resources :legislations, only: [:show]
|
||||
|
||||
resources :annotations do
|
||||
collection do
|
||||
get :search
|
||||
end
|
||||
get :search, on: :collection
|
||||
end
|
||||
|
||||
resources :users, only: [:show]
|
||||
|
||||
resource :account, controller: "account", only: [:show, :update, :delete] do
|
||||
collection { get :erase }
|
||||
get :erase, on: :collection
|
||||
end
|
||||
|
||||
resources :notifications, only: [:index, :show] do
|
||||
collection { put :mark_all_as_read }
|
||||
put :mark_all_as_read, on: :collection
|
||||
end
|
||||
|
||||
resource :verification, controller: "verification", only: [:show]
|
||||
@@ -102,7 +102,7 @@ Rails.application.routes.draw do
|
||||
namespace :admin do
|
||||
root to: "dashboard#index"
|
||||
resources :organizations, only: :index do
|
||||
collection { get :search }
|
||||
get :search, on: :collection
|
||||
member do
|
||||
put :verify
|
||||
put :reject
|
||||
@@ -146,20 +146,20 @@ Rails.application.routes.draw do
|
||||
|
||||
resources :tags, only: [:index, :create, :update, :destroy]
|
||||
resources :officials, only: [:index, :edit, :update, :destroy] do
|
||||
collection { get :search}
|
||||
get :search, on: :collection
|
||||
end
|
||||
|
||||
resources :settings, only: [:index, :update]
|
||||
resources :moderators, only: [:index, :create, :destroy] do
|
||||
collection { get :search }
|
||||
get :search, on: :collection
|
||||
end
|
||||
|
||||
resources :valuators, only: [:index, :create] do
|
||||
collection { get :search }
|
||||
get :search, on: :collection
|
||||
end
|
||||
|
||||
resources :verifications, controller: :verifications, only: :index do
|
||||
collection { get :search}
|
||||
get :search, on: :collection
|
||||
end
|
||||
|
||||
resource :activity, controller: :activity, only: :show
|
||||
@@ -181,30 +181,18 @@ Rails.application.routes.draw do
|
||||
end
|
||||
|
||||
resources :debates, only: :index do
|
||||
member do
|
||||
put :hide
|
||||
end
|
||||
collection do
|
||||
put :moderate
|
||||
end
|
||||
put :hide, on: :member
|
||||
put :moderate, on: :collection
|
||||
end
|
||||
|
||||
resources :proposals, only: :index do
|
||||
member do
|
||||
put :hide
|
||||
end
|
||||
collection do
|
||||
put :moderate
|
||||
end
|
||||
put :hide, on: :member
|
||||
put :moderate, on: :collection
|
||||
end
|
||||
|
||||
resources :comments, only: :index do
|
||||
member do
|
||||
put :hide
|
||||
end
|
||||
collection do
|
||||
put :moderate
|
||||
end
|
||||
put :hide, on: :member
|
||||
put :moderate, on: :collection
|
||||
end
|
||||
end
|
||||
|
||||
@@ -212,9 +200,7 @@ Rails.application.routes.draw do
|
||||
root to: "spending_proposals#index"
|
||||
|
||||
resources :spending_proposals, only: [:index, :show, :edit] do
|
||||
member do
|
||||
patch :valuate
|
||||
end
|
||||
patch :valuate, on: :member
|
||||
end
|
||||
end
|
||||
|
||||
@@ -222,9 +208,7 @@ Rails.application.routes.draw do
|
||||
root to: "dashboard#index"
|
||||
|
||||
resources :document_verifications, only: [:index, :new, :create] do
|
||||
collection do
|
||||
post :check
|
||||
end
|
||||
post :check, on: :collection
|
||||
end
|
||||
|
||||
resources :email_verifications, only: [:new, :create]
|
||||
@@ -232,23 +216,24 @@ Rails.application.routes.draw do
|
||||
resources :users, only: [:new, :create] do
|
||||
collection do
|
||||
delete :logout
|
||||
delete :erase
|
||||
end
|
||||
end
|
||||
|
||||
resource :account, controller: "account", only: [:show]
|
||||
|
||||
get 'sign_in', to: 'sessions#create'
|
||||
|
||||
resource :session, only: [:create, :destroy]
|
||||
resources :proposals, only: [:index, :new, :create, :show] do
|
||||
member do
|
||||
post :vote
|
||||
end
|
||||
|
||||
collection do
|
||||
get :print
|
||||
end
|
||||
post :vote, on: :member
|
||||
get :print, on: :collection
|
||||
end
|
||||
|
||||
resources :spending_proposals, only: [:new, :create, :show]
|
||||
resources :spending_proposals, only: [:index, :new, :create, :show] do
|
||||
post :vote, on: :member
|
||||
get :print, on: :collection
|
||||
end
|
||||
end
|
||||
|
||||
if Rails.env.development?
|
||||
|
||||
@@ -13,6 +13,7 @@ Setting.create(key: 'max_votes_for_debate_edit', value: '1000')
|
||||
Setting.create(key: 'max_votes_for_proposal_edit', value: '1000')
|
||||
Setting.create(key: 'proposal_code_prefix', value: 'MAD')
|
||||
Setting.create(key: 'votes_for_proposal_success', value: '100')
|
||||
Setting.create(key: 'comments_body_max_length', value: '1000')
|
||||
|
||||
Setting.create(key: 'blog_url', value: '/blog')
|
||||
Setting.create(key: 'url', value: 'http://localhost:3000')
|
||||
@@ -20,6 +21,7 @@ Setting.create(key: 'org_name', value: 'Consul')
|
||||
Setting.create(key: 'place_name', value: 'City')
|
||||
Setting.create(key: 'feature.debates', value: "true")
|
||||
Setting.create(key: 'feature.spending_proposals', value: "true")
|
||||
Setting.create(key: 'feature.spending_proposal_features.voting_allowed', value: "true")
|
||||
Setting.create(key: 'feature.twitter_login', value: "true")
|
||||
Setting.create(key: 'feature.facebook_login', value: "true")
|
||||
Setting.create(key: 'feature.google_login', value: "true")
|
||||
@@ -46,6 +48,12 @@ moderator.create_moderator
|
||||
valuator = create_user('valuator@madrid.es', 'valuator')
|
||||
valuator.create_valuator
|
||||
|
||||
level_2 = create_user('leveltwo@madrid.es', 'level 2')
|
||||
level_2.update(residence_verified_at: Time.now, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: "2222222222", document_type: "1" )
|
||||
|
||||
verified = create_user('verified@madrid.es', 'verified')
|
||||
verified.update(residence_verified_at: Time.now, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.now, document_number: "3333333333")
|
||||
|
||||
(1..10).each do |i|
|
||||
org_name = Faker::Company.name
|
||||
org_user = create_user("org#{i}@madrid.es", org_name)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddUnfeasibleEmailSentAtToSpendingProposals < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spending_proposals, :unfeasible_email_sent_at, :datetime, default: nil
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddVotesUpToSpendingProposals < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spending_proposals, :cached_votes_up, :integer, default: 0
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
class AddTsvectorToSpendingProposals < ActiveRecord::Migration
|
||||
|
||||
def change
|
||||
add_column :spending_proposals, :tsv, :tsvector
|
||||
add_index :spending_proposals, :tsv, using: "gin"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddResponsibleNameToSpendingProposals < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spending_proposals, :responsible_name, :string, limit: 60
|
||||
end
|
||||
end
|
||||
6
db/migrate/20160411161531_add_genre_and_dob_to_users.rb
Normal file
6
db/migrate/20160411161531_add_genre_and_dob_to_users.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class AddGenreAndDobToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :genre, :string, index: true, limit: 10
|
||||
add_column :users, :date_of_birth, :datetime, index: true
|
||||
end
|
||||
end
|
||||
5
db/migrate/20160413122359_rename_genre_to_gender.rb
Normal file
5
db/migrate/20160413122359_rename_genre_to_gender.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class RenameGenreToGender < ActiveRecord::Migration
|
||||
def change
|
||||
rename_column :users, :genre, :gender
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user