fixes conflicts with budget

This commit is contained in:
rgarcia
2016-07-27 11:41:46 +02:00
260 changed files with 8185 additions and 1693 deletions

View File

@@ -1 +1 @@
2.2.3 2.3.1

View File

@@ -9,7 +9,7 @@ require 'capistrano/bundler'
require 'capistrano/rails/assets' require 'capistrano/rails/assets'
require 'capistrano/rails/migrations' require 'capistrano/rails/migrations'
#require 'capistrano/passenger' #require 'capistrano/passenger'
require 'capistrano/delayed-job' require 'capistrano/delayed_job'
require 'whenever/capistrano' require 'whenever/capistrano'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined # Load custom tasks from `lib/capistrano/tasks` if you have any defined

22
Gemfile
View File

@@ -1,7 +1,7 @@
source 'https://rubygems.org' source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.6' gem 'rails', '4.2.7'
# Use PostgreSQL # Use PostgreSQL
gem 'pg' gem 'pg'
# Use SCSS for stylesheets # Use SCSS for stylesheets
@@ -9,7 +9,7 @@ gem 'sass-rails', '~> 5.0', '>= 5.0.4'
# Use Uglifier as compressor for JavaScript assets # Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0' gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views # Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0' gem 'coffee-rails', '~> 4.2.1'
# See https://github.com/rails/execjs#readme for more supported runtimes # See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby # gem 'therubyracer', platforms: :ruby
@@ -34,21 +34,21 @@ gem 'responders'
gem 'foundation-rails' gem 'foundation-rails'
gem 'foundation_rails_helper' gem 'foundation_rails_helper'
gem 'acts_as_votable' gem 'acts_as_votable'
gem 'ckeditor', '~> 4.1.5' gem 'ckeditor', '~> 4.2.0'
gem 'invisible_captcha', '~> 0.8.2' gem 'invisible_captcha', '~> 0.9.1'
gem 'cancancan' gem 'cancancan'
gem 'social-share-button', git: 'https://github.com/huacnlee/social-share-button.git', ref: 'e46a6a3e82b86023bc' gem 'social-share-button'
gem 'initialjs-rails', '0.2.0.1' gem 'initialjs-rails', '0.2.0.1'
gem 'unicorn', '~> 5.1.0' gem 'unicorn', '~> 5.1.0'
gem 'paranoia' gem 'paranoia'
gem 'rinku', require: 'rails_rinku' gem 'rinku', require: 'rails_rinku'
gem 'savon' gem 'savon'
gem 'dalli' gem 'dalli'
gem 'rollbar', '~> 2.11.0' gem 'rollbar', '~> 2.12.0'
gem 'delayed_job_active_record', '~> 4.1.0' gem 'delayed_job_active_record', '~> 4.1.0'
gem 'daemons' gem 'daemons'
gem 'devise-async' gem 'devise-async'
gem 'newrelic_rpm', '~> 3.14' gem 'newrelic_rpm', '~> 3.16'
gem 'whenever', require: false gem 'whenever', require: false
gem 'pg_search' gem 'pg_search'
@@ -66,7 +66,7 @@ group :development, :test do
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring' gem 'spring'
gem 'spring-commands-rspec' gem 'spring-commands-rspec'
gem 'rspec-rails', '~> 3.3' gem 'rspec-rails', '~> 3.5'
gem 'capybara' gem 'capybara'
gem 'factory_girl_rails' gem 'factory_girl_rails'
gem 'fuubar' gem 'fuubar'
@@ -74,9 +74,9 @@ group :development, :test do
gem 'quiet_assets' gem 'quiet_assets'
gem 'letter_opener_web', '~> 1.3.0' gem 'letter_opener_web', '~> 1.3.0'
gem 'i18n-tasks' gem 'i18n-tasks'
gem 'capistrano', '3.4.1', require: false gem 'capistrano', '3.5.0', require: false
gem "capistrano-bundler", '1.1.4', require: false gem "capistrano-bundler", '1.1.4', require: false
gem "capistrano-rails", '1.1.6', require: false gem "capistrano-rails", '1.1.7', require: false
gem "capistrano-rvm", require: false gem "capistrano-rvm", require: false
gem 'capistrano3-delayed-job', '~> 1.0' gem 'capistrano3-delayed-job', '~> 1.0'
gem "bullet" gem "bullet"
@@ -92,5 +92,5 @@ end
group :development do group :development do
# Access an IRB console on exception pages or by using <%= console %> in views # Access an IRB console on exception pages or by using <%= console %> in views
gem 'web-console', '~> 3.0' gem 'web-console', '3.3.0'
end end

View File

@@ -1,45 +1,36 @@
GIT
remote: https://github.com/huacnlee/social-share-button.git
revision: e46a6a3e82b86023bc43b72c9379d3c6afe36b6b
ref: e46a6a3e82b86023bc
specs:
social-share-button (0.1.9)
coffee-rails
sass-rails
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
actionmailer (4.2.6) actionmailer (4.2.7)
actionpack (= 4.2.6) actionpack (= 4.2.7)
actionview (= 4.2.6) actionview (= 4.2.7)
activejob (= 4.2.6) activejob (= 4.2.7)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.6) actionpack (4.2.7)
actionview (= 4.2.6) actionview (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
rack (~> 1.6) rack (~> 1.6)
rack-test (~> 0.6.2) rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.6) actionview (4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5) rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (4.2.6) activejob (4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
globalid (>= 0.3.0) globalid (>= 0.3.0)
activemodel (4.2.6) activemodel (4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
builder (~> 3.1) builder (~> 3.1)
activerecord (4.2.6) activerecord (4.2.7)
activemodel (= 4.2.6) activemodel (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
arel (~> 6.0) arel (~> 6.0)
activesupport (4.2.6) activesupport (4.2.7)
i18n (~> 0.7) i18n (~> 0.7)
json (~> 1.7, >= 1.7.7) json (~> 1.7, >= 1.7.7)
minitest (~> 5.1) minitest (~> 5.1)
@@ -49,7 +40,7 @@ GEM
activerecord (>= 3.2, < 5) activerecord (>= 3.2, < 5)
acts_as_votable (0.10.0) acts_as_votable (0.10.0)
addressable (2.4.0) addressable (2.4.0)
ahoy_matey (1.4.0) ahoy_matey (1.4.2)
addressable addressable
browser (~> 2.0) browser (~> 2.0)
geocoder geocoder
@@ -57,9 +48,11 @@ GEM
railties railties
referer-parser (>= 0.3.0) referer-parser (>= 0.3.0)
request_store request_store
safely_block safely_block (>= 0.1.1)
user_agent_parser user_agent_parser
uuidtools uuidtools
airbrussh (1.0.2)
sshkit (>= 1.6.1, != 1.7.0)
akami (1.3.1) akami (1.3.1)
gyoku (>= 0.4.0) gyoku (>= 0.4.0)
nokogiri nokogiri
@@ -72,21 +65,24 @@ GEM
babel-source (>= 4.0, < 6) babel-source (>= 4.0, < 6)
execjs (~> 2.0) execjs (~> 2.0)
bcrypt (3.1.11) bcrypt (3.1.11)
browser (2.1.0) browser (2.2.0)
builder (3.2.2) builder (3.2.2)
bullet (5.0.0) bullet (5.1.1)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
uniform_notifier (~> 1.9.0) uniform_notifier (~> 1.10.0)
byebug (9.0.4) byebug (9.0.5)
cancancan (1.14.0) cancancan (1.15.0)
capistrano (3.4.1) capistrano (3.5.0)
airbrussh (>= 1.0.0)
capistrano-harrow
i18n i18n
rake (>= 10.0.0) rake (>= 10.0.0)
sshkit (~> 1.3) sshkit (>= 1.9.0)
capistrano-bundler (1.1.4) capistrano-bundler (1.1.4)
capistrano (~> 3.1) capistrano (~> 3.1)
sshkit (~> 1.2) sshkit (~> 1.2)
capistrano-rails (1.1.6) capistrano-harrow (0.5.2)
capistrano-rails (1.1.7)
capistrano (~> 3.1) capistrano (~> 3.1)
capistrano-bundler (~> 1.1) capistrano-bundler (~> 1.1)
capistrano-rvm (0.1.2) capistrano-rvm (0.1.2)
@@ -102,7 +98,7 @@ GEM
rack-test (>= 0.5.4) rack-test (>= 0.5.4)
xpath (~> 2.0) xpath (~> 2.0)
chronic (0.10.2) chronic (0.10.2)
ckeditor (4.1.6) ckeditor (4.2.0)
cocaine cocaine
orm_adapter (~> 0.5.0) orm_adapter (~> 0.5.0)
climate_control (0.0.3) climate_control (0.0.3)
@@ -110,17 +106,17 @@ GEM
cliver (0.3.2) cliver (0.3.2)
cocaine (0.5.8) cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0) climate_control (>= 0.0.3, < 1.0)
coffee-rails (4.1.1) coffee-rails (4.2.1)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.1.x) railties (>= 4.0.0, < 5.2.x)
coffee-script (2.4.1) coffee-script (2.4.1)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.10.0) coffee-script-source (1.10.0)
concurrent-ruby (1.0.2) concurrent-ruby (1.0.2)
coveralls (0.8.13) coveralls (0.8.14)
json (~> 1.8) json (>= 1.8, < 3)
simplecov (~> 0.11.0) simplecov (~> 0.12.0)
term-ansicolor (~> 1.3) term-ansicolor (~> 1.3)
thor (~> 0.19.1) thor (~> 0.19.1)
tins (~> 1.6.0) tins (~> 1.6.0)
@@ -133,15 +129,15 @@ GEM
delayed_job_active_record (4.1.1) delayed_job_active_record (4.1.1)
activerecord (>= 3.0, < 5.1) activerecord (>= 3.0, < 5.1)
delayed_job (>= 3.0, < 5) delayed_job (>= 3.0, < 5)
devise (3.5.7) devise (3.5.10)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5) railties (>= 3.2.6, < 5)
responders responders
thread_safe (~> 0.1) thread_safe (~> 0.1)
warden (~> 1.2.3) warden (~> 1.2.3)
devise-async (0.10.1) devise-async (0.10.2)
devise (~> 3.2) devise (>= 3.2, < 4.0)
diff-lcs (1.2.5) diff-lcs (1.2.5)
docile (1.1.5) docile (1.1.5)
easy_translate (0.5.0) easy_translate (0.5.0)
@@ -154,33 +150,33 @@ GEM
mail (~> 2.6.3) mail (~> 2.6.3)
errbase (0.0.3) errbase (0.0.3)
erubis (2.7.0) erubis (2.7.0)
execjs (2.6.0) execjs (2.7.0)
factory_girl (4.7.0) factory_girl (4.7.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
factory_girl_rails (4.7.0) factory_girl_rails (4.7.0)
factory_girl (~> 4.7.0) factory_girl (~> 4.7.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faker (1.6.3) faker (1.6.5)
i18n (~> 0.5) i18n (~> 0.5)
faraday (0.9.2) faraday (0.9.2)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
foundation-rails (6.2.1.0) foundation-rails (6.2.3.0)
railties (>= 3.1.0) railties (>= 3.1.0)
sass (>= 3.3.0, < 3.5) sass (>= 3.3.0, < 3.5)
sprockets-es6 (>= 0.9.0) sprockets-es6 (>= 0.9.0)
foundation_rails_helper (1.1.0) foundation_rails_helper (1.2.1)
actionpack (~> 4.1) actionpack (>= 4.1)
activemodel (~> 4.1) activemodel (>= 4.1)
activesupport (~> 4.1) activesupport (>= 4.1)
railties (~> 4.1) railties (>= 4.1)
tzinfo (~> 1.2, >= 1.2.2) tzinfo (~> 1.2, >= 1.2.2)
fuubar (2.0.0) fuubar (2.1.1)
rspec (~> 3.0) rspec (~> 3.0)
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
geocoder (1.3.4) geocoder (1.3.7)
globalid (0.3.6) globalid (0.3.6)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
groupdate (2.5.3) groupdate (3.0.1)
activesupport (>= 3) activesupport (>= 3)
gyoku (1.3.1) gyoku (1.3.1)
builder (>= 2.1.2) builder (>= 2.1.2)
@@ -202,7 +198,7 @@ GEM
terminal-table (>= 1.5.1) terminal-table (>= 1.5.1)
initialjs-rails (0.2.0.1) initialjs-rails (0.2.0.1)
railties (>= 3.1, < 5.0) railties (>= 3.1, < 5.0)
invisible_captcha (0.8.2) invisible_captcha (0.9.1)
rails rails
jquery-rails (4.1.1) jquery-rails (4.1.1)
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
@@ -212,7 +208,7 @@ GEM
railties (>= 3.2.16) railties (>= 3.2.16)
json (1.8.3) json (1.8.3)
jwt (1.5.4) jwt (1.5.4)
kaminari (0.16.3) kaminari (0.17.0)
actionpack (>= 3.0.0) actionpack (>= 3.0.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
kgio (2.10.0) kgio (2.10.0)
@@ -228,20 +224,21 @@ GEM
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.6.4) mail (2.6.4)
mime-types (>= 1.16, < 4) mime-types (>= 1.16, < 4)
mime-types (3.0) mime-types (3.1)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2016.0221) mime-types-data (3.2016.0521)
mini_portile2 (2.0.0) mini_portile2 (2.1.0)
minitest (5.9.0) minitest (5.9.0)
multi_json (1.12.1) multi_json (1.12.1)
multi_xml (0.5.5) multi_xml (0.5.5)
multipart-post (2.0.0) multipart-post (2.0.0)
net-scp (1.2.1) net-scp (1.2.1)
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (3.1.1) net-ssh (3.2.0)
newrelic_rpm (3.15.2.317) newrelic_rpm (3.16.0.318)
nokogiri (1.6.7.2) nokogiri (1.6.8)
mini_portile2 (~> 2.0.0.rc2) mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
nori (2.6.0) nori (2.6.0)
oauth (0.5.0) oauth (0.5.0)
oauth2 (1.0.0) oauth2 (1.0.0)
@@ -275,14 +272,14 @@ GEM
parser (2.3.0.6) parser (2.3.0.6)
ast (~> 2.2) ast (~> 2.2)
pg (0.18.4) pg (0.18.4)
pg_search (1.0.5) pg_search (1.0.6)
activerecord (>= 3.1) activerecord (>= 3.1)
activesupport (>= 3.1) activesupport (>= 3.1)
arel arel
poltergeist (1.9.0) pkg-config (1.1.7)
poltergeist (1.10.0)
capybara (~> 2.1) capybara (~> 2.1)
cliver (~> 0.3.1) cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0) websocket-driver (>= 0.2.0)
quiet_assets (1.1.0) quiet_assets (1.1.0)
railties (>= 3.1, < 5.0) railties (>= 3.1, < 5.0)
@@ -293,16 +290,16 @@ GEM
rack rack
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (4.2.6) rails (4.2.7)
actionmailer (= 4.2.6) actionmailer (= 4.2.7)
actionpack (= 4.2.6) actionpack (= 4.2.7)
actionview (= 4.2.6) actionview (= 4.2.7)
activejob (= 4.2.6) activejob (= 4.2.7)
activemodel (= 4.2.6) activemodel (= 4.2.7)
activerecord (= 4.2.6) activerecord (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
bundler (>= 1.3.0, < 2.0) bundler (>= 1.3.0, < 2.0)
railties (= 4.2.6) railties (= 4.2.7)
sprockets-rails sprockets-rails
rails-deprecated_sanitizer (1.0.3) rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha) activesupport (>= 4.2.0.alpha)
@@ -312,49 +309,49 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1) rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (4.2.6) railties (4.2.7)
actionpack (= 4.2.6) actionpack (= 4.2.7)
activesupport (= 4.2.6) activesupport (= 4.2.7)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
raindrops (0.16.0) raindrops (0.16.0)
rake (11.1.2) rake (11.2.2)
redcarpet (3.3.4) redcarpet (3.3.4)
referer-parser (0.3.0) referer-parser (0.3.0)
request_store (1.3.1) request_store (1.3.1)
responders (2.2.0) responders (2.2.0)
railties (>= 4.2.0, < 5.1) railties (>= 4.2.0, < 5.1)
rinku (2.0.0) rinku (2.0.0)
rollbar (2.11.3) rollbar (2.12.0)
multi_json multi_json
rspec (3.4.0) rspec (3.5.0)
rspec-core (~> 3.4.0) rspec-core (~> 3.5.0)
rspec-expectations (~> 3.4.0) rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.4.0) rspec-mocks (~> 3.5.0)
rspec-core (3.4.4) rspec-core (3.5.1)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-expectations (3.4.0) rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-mocks (3.4.1) rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-rails (3.4.2) rspec-rails (3.5.1)
actionpack (>= 3.0, < 4.3) actionpack (>= 3.0)
activesupport (>= 3.0, < 4.3) activesupport (>= 3.0)
railties (>= 3.0, < 4.3) railties (>= 3.0)
rspec-core (~> 3.4.0) rspec-core (~> 3.5.0)
rspec-expectations (~> 3.4.0) rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.4.0) rspec-mocks (~> 3.5.0)
rspec-support (~> 3.4.0) rspec-support (~> 3.5.0)
rspec-support (3.4.1) rspec-support (3.5.0)
ruby-progressbar (1.7.5) ruby-progressbar (1.8.1)
safe_yaml (1.0.4) safe_yaml (1.0.4)
safely_block (0.1.0) safely_block (0.1.1)
errbase errbase
sass (3.4.22) sass (3.4.22)
sass-rails (5.0.4) sass-rails (5.0.5)
railties (>= 4.0.0, < 5.0) railties (>= 4.0.0, < 6)
sass (~> 3.1) sass (~> 3.1)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0) sprockets-rails (>= 2.0, < 4.0)
@@ -367,26 +364,29 @@ GEM
nokogiri (>= 1.4.0) nokogiri (>= 1.4.0)
nori (~> 2.4) nori (~> 2.4)
wasabi (~> 3.4) wasabi (~> 3.4)
simplecov (0.11.2) simplecov (0.12.0)
docile (~> 1.1.0) docile (~> 1.1.0)
json (~> 1.8) json (>= 1.8, < 3)
simplecov-html (~> 0.10.0) simplecov-html (~> 0.10.0)
simplecov-html (0.10.0) simplecov-html (0.10.0)
spring (1.7.1) social-share-button (0.3.1)
coffee-rails
sass-rails
spring (1.7.2)
spring-commands-rspec (1.0.4) spring-commands-rspec (1.0.4)
spring (>= 0.9.1) spring (>= 0.9.1)
sprockets (3.6.0) sprockets (3.6.3)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
sprockets-es6 (0.9.0) sprockets-es6 (0.9.0)
babel-source (>= 5.8.11) babel-source (>= 5.8.11)
babel-transpiler babel-transpiler
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sprockets-rails (3.0.4) sprockets-rails (3.1.1)
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sshkit (1.10.0) sshkit (1.11.1)
net-scp (>= 1.1.2) net-scp (>= 1.1.2)
net-ssh (>= 2.8.0) net-ssh (>= 2.8.0)
term-ansicolor (1.3.2) term-ansicolor (1.3.2)
@@ -395,7 +395,7 @@ GEM
thor (0.19.1) thor (0.19.1)
thread (0.2.2) thread (0.2.2)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (2.0.4) tilt (2.0.5)
tins (1.6.0) tins (1.6.0)
tolk (1.9.3) tolk (1.9.3)
rails (>= 4.0, < 4.3) rails (>= 4.0, < 4.3)
@@ -413,7 +413,7 @@ GEM
unicorn (5.1.0) unicorn (5.1.0)
kgio (~> 2.6) kgio (~> 2.6)
raindrops (~> 0.7) raindrops (~> 0.7)
uniform_notifier (1.9.0) uniform_notifier (1.10.0)
user_agent_parser (2.3.0) user_agent_parser (2.3.0)
uuidtools (2.1.5) uuidtools (2.1.5)
warden (1.2.6) warden (1.2.6)
@@ -421,14 +421,14 @@ GEM
wasabi (3.5.0) wasabi (3.5.0)
httpi (~> 2.0) httpi (~> 2.0)
nokogiri (>= 1.4.2) nokogiri (>= 1.4.2)
web-console (3.1.1) web-console (3.3.0)
activemodel (>= 4.2) activemodel (>= 4.2)
debug_inspector debug_inspector
railties (>= 4.2) railties (>= 4.2)
websocket-driver (0.6.3) websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2) websocket-extensions (0.1.2)
whenever (0.9.4) whenever (0.9.7)
chronic (>= 0.6.3) chronic (>= 0.6.3)
xpath (2.0.0) xpath (2.0.0)
nokogiri (~> 1.3) nokogiri (~> 1.3)
@@ -445,14 +445,14 @@ DEPENDENCIES
bullet bullet
byebug byebug
cancancan cancancan
capistrano (= 3.4.1) capistrano (= 3.5.0)
capistrano-bundler (= 1.1.4) capistrano-bundler (= 1.1.4)
capistrano-rails (= 1.1.6) capistrano-rails (= 1.1.7)
capistrano-rvm capistrano-rvm
capistrano3-delayed-job (~> 1.0) capistrano3-delayed-job (~> 1.0)
capybara capybara
ckeditor (~> 4.1.5) ckeditor (~> 4.2.0)
coffee-rails (~> 4.1.0) coffee-rails (~> 4.2.1)
coveralls coveralls
daemons daemons
dalli dalli
@@ -469,13 +469,13 @@ DEPENDENCIES
groupdate groupdate
i18n-tasks i18n-tasks
initialjs-rails (= 0.2.0.1) initialjs-rails (= 0.2.0.1)
invisible_captcha (~> 0.8.2) invisible_captcha (~> 0.9.1)
jquery-rails jquery-rails
jquery-ui-rails jquery-ui-rails
kaminari kaminari
launchy launchy
letter_opener_web (~> 1.3.0) letter_opener_web (~> 1.3.0)
newrelic_rpm (~> 3.14) newrelic_rpm (~> 3.16)
omniauth omniauth
omniauth-facebook (~> 3.0.0) omniauth-facebook (~> 3.0.0)
omniauth-google-oauth2 (~> 0.4.0) omniauth-google-oauth2 (~> 0.4.0)
@@ -485,15 +485,15 @@ DEPENDENCIES
pg_search pg_search
poltergeist poltergeist
quiet_assets quiet_assets
rails (= 4.2.6) rails (= 4.2.7)
redcarpet redcarpet
responders responders
rinku rinku
rollbar (~> 2.11.0) rollbar (~> 2.12.0)
rspec-rails (~> 3.3) rspec-rails (~> 3.5)
sass-rails (~> 5.0, >= 5.0.4) sass-rails (~> 5.0, >= 5.0.4)
savon savon
social-share-button! social-share-button
spring spring
spring-commands-rspec spring-commands-rspec
tolk tolk
@@ -501,8 +501,8 @@ DEPENDENCIES
turnout turnout
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
unicorn (~> 5.1.0) unicorn (~> 5.1.0)
web-console (~> 3.0) web-console (= 3.3.0)
whenever whenever
BUNDLED WITH BUNDLED WITH
1.12.4 1.12.5

View File

@@ -8,17 +8,13 @@ Citizen Participation and Open Government Application
[![Build Status](https://travis-ci.org/consul/consul.svg?branch=master)](https://travis-ci.org/consul/consul) [![Build Status](https://travis-ci.org/consul/consul.svg?branch=master)](https://travis-ci.org/consul/consul)
[![Code Climate](https://codeclimate.com/github/consul/consul/badges/gpa.svg)](https://codeclimate.com/github/consul/consul) [![Code Climate](https://codeclimate.com/github/consul/consul/badges/gpa.svg)](https://codeclimate.com/github/consul/consul)
[![Dependency Status](https://gemnasium.com/consul/consul.svg)](https://gemnasium.com/consul/consul) [![Dependency Status](https://gemnasium.com/consul/consul.svg)](https://gemnasium.com/consul/consul)
[![Coverage Status](https://coveralls.io/repos/consul/consul/badge.svg?branch=master&service=github)](https://coveralls.io/github/consul/consul?branch=master) [![Coverage Status](https://coveralls.io/repos/github/consul/consul/badge.svg?branch=master)](https://coveralls.io/github/consul/consul?branch=master)
This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website
## Current state ## Current state
Development started on [2015 July 15th](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6). Code was deployed to production on 2015 september 7th to [decide.madrid.es](https://decide.madrid.es). Since then new features are added often. You can take a look at a roadmap and future features in the [open issues list](https://github.com/consul/consul/issues). Development started on [2015 July 15th](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6). Code was deployed to production on 2015 september 7th to [decide.madrid.es](https://decide.madrid.es). Since then new features are added often. You can take a look at the current features in the [docs](https://github.com/consul/consul/tree/master/doc) and future features in the [open issues list](https://github.com/consul/consul/issues).
## Roadmap
See [ROADMAP_ES.md](ROADMAP_ES.md)
## Tech stack ## Tech stack
@@ -39,7 +35,7 @@ cp config/secrets.yml.example config/secrets.yml
rake db:create rake db:create
bin/rake db:setup bin/rake db:setup
bin/rake db:dev_seed bin/rake db:dev_seed
RAILS_ENV=test bin/rake db:setup RAILS_ENV=test rake db:setup
``` ```
Run the app locally: Run the app locally:
@@ -58,12 +54,12 @@ bin/rspec
You can use the default admin user from the seeds file: You can use the default admin user from the seeds file:
**user:** admin@madrid.es **user:** admin@consul.dev
**pass:** 12345678 **pass:** 12345678
But for some actions like voting, you will need a verified user, the seeds file also includes one: But for some actions like voting, you will need a verified user, the seeds file also includes one:
**user:** verified@madrid.es **user:** verified@consul.dev
**pass:** 12345678 **pass:** 12345678
### OAuth ### OAuth

View File

@@ -8,17 +8,13 @@ Aplicación de Participación Ciudadana y Gobierno Abierto
[![Build Status](https://travis-ci.org/consul/consul.svg?branch=master)](https://travis-ci.org/consul/consul) [![Build Status](https://travis-ci.org/consul/consul.svg?branch=master)](https://travis-ci.org/consul/consul)
[![Code Climate](https://codeclimate.com/github/consul/consul/badges/gpa.svg)](https://codeclimate.com/github/consul/consul) [![Code Climate](https://codeclimate.com/github/consul/consul/badges/gpa.svg)](https://codeclimate.com/github/consul/consul)
[![Dependency Status](https://gemnasium.com/consul/consul.svg)](https://gemnasium.com/consul/consul) [![Dependency Status](https://gemnasium.com/consul/consul.svg)](https://gemnasium.com/consul/consul)
[![Coverage Status](https://coveralls.io/repos/consul/consul/badge.svg?branch=master&service=github)](https://coveralls.io/github/consul/consul?branch=master) [![Coverage Status](https://coveralls.io/repos/github/consul/consul/badge.svg?branch=master)](https://coveralls.io/github/consul/consul?branch=master)
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid. Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid.
## Estado del proyecto ## Estado del proyecto
El desarrollo de esta aplicación comenzó el [15 de Julio de 2015](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6) y el código fue puesto en producción el día 7 de Septiembre de 2015 en [decide.madrid.es](https://decide.madrid.es). Desde entonces se le añaden mejoras y funcionalidades constantemente. La evolución y futura lista de funcionalidades a implementar se pueden consultar en la lista de [tareas por hacer](https://github.com/consul/consul/issues). El desarrollo de esta aplicación comenzó el [15 de Julio de 2015](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6) y el código fue puesto en producción el día 7 de Septiembre de 2015 en [decide.madrid.es](https://decide.madrid.es). Desde entonces se le añaden mejoras y funcionalidades constantemente. Las funcionalidades actuales se pueden consultar en la [documentación](https://github.com/consul/consul/tree/master/doc) y las siguientes funcionaliades en la lista de [tareas por hacer](https://github.com/consul/consul/issues).
## Hoja de ruta
Ver fichero [ROADMAP_ES.md](ROADMAP_ES.md)
## Tecnología ## Tecnología
@@ -39,7 +35,7 @@ cp config/secrets.yml.example config/secrets.yml
rake db:create rake db:create
bin/rake db:setup bin/rake db:setup
bin/rake db:dev_seed bin/rake db:dev_seed
RAILS_ENV=test bin/rake db:setup RAILS_ENV=test rake db:setup
``` ```
Para ejecutar la aplicación en local: Para ejecutar la aplicación en local:
@@ -57,12 +53,12 @@ bin/rspec
Puedes usar el usuario administrador por defecto del fichero seeds: Puedes usar el usuario administrador por defecto del fichero seeds:
**user:** admin@madrid.es **user:** admin@consul.dev
**pass:** 12345678 **pass:** 12345678
Pero para ciertas acciones, como apoyar, necesitarás un usuario verificado, el fichero seeds proporciona uno: Pero para ciertas acciones, como apoyar, necesitarás un usuario verificado, el fichero seeds proporciona uno:
**user:** verified@madrid.es **user:** verified@consul.dev
**pass:** 12345678 **pass:** 12345678

View File

@@ -1,26 +0,0 @@
## Hoja de ruta
Las necesidades y líneas de desarrollo de Consul a corto plazo se actualizan continuamente, y son añadidas como Issues https://github.com/consul/consul/issues La hoja de ruta de desarrollo a medio plazo comprende lo siguiente:
## Debates y propuestas
Entre las mejoras a desarrollar destacamos las siguientes:
- Búsquedas avanzadas
- Notificaciones de usuarios
- Listas de correo informativas para los usuarios
- Clasificaciones temáticas y locales
- Mejora del sistema de etiquetado
- Sistema de identificación de propuestas similares
- Mejora de algoritmos de ordenación
- Ampliación de licencias de contenidos
- Añadido de idiomas disponibles
- Universalización del código, y facilitación de adaptación a diferentes sistemas locales
- Creación de sección de procesos participativos ad-hoc
## Presupuestos participativos
Este espacio permitirá que una cierta cantidad de dinero se distribuya por decisión ciudadana. Para ello permitirá: recibir propuestas para este fin; que dichas propuestas sean tasadas y evaluadas por un cierto perfil de usuarios mostrando dicho trabajo junto a las mismas; mostrar las propuestas de tal forma que los usuarios verificados puedan votar un conjunto de ellas acorde con la cantidad de dinero reservada. El mecanismo contemplará mecanismos de pre-selección y selección, además de categorizaciones geográficas o temáticas de las propuestas.
## Legislación colaborativa
Este módulo permitirá la participación ciudadana en todas las fases de un desarrollo legislativo. Desde la propuesta y selección de los redactores y expertos de la legislación, pasando por la fase de debate y propuesta asociada a la misma (que a su vez se dividirá en espacios de debate libre y mecanismos de pregunta-respuesta), hasta la redacción colaborativa y la revisión detallada del texto creado. El módulo permitirá activar independientemente las diferentes fases del proceso, de tal forma que su uso pueda extenderse mucho más allá del caso de la redacción colaborativa.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

View File

@@ -23,6 +23,8 @@ App.AdvancedSearch =
$('.js-calendar').datepicker $('.js-calendar').datepicker
regional: locale regional: locale
maxDate: "+0d" maxDate: "+0d"
$('.js-calendar-full').datepicker
regional: locale
initialize: -> initialize: ->
App.AdvancedSearch.init_calendar() App.AdvancedSearch.init_calendar()

View File

@@ -44,6 +44,7 @@
//= require tracks //= require tracks
//= require valuation_spending_proposal_form //= require valuation_spending_proposal_form
//= require embed_video //= require embed_video
//= require banners
var initialize_modules = function() { var initialize_modules = function() {
App.Comments.initialize(); App.Comments.initialize();
@@ -63,6 +64,7 @@ var initialize_modules = function() {
App.Tracks.initialize(); App.Tracks.initialize();
App.ValuationSpendingProposalForm.initialize(); App.ValuationSpendingProposalForm.initialize();
App.EmbedVideo.initialize(); App.EmbedVideo.initialize();
App.Banners.initialize();
}; };
$(function(){ $(function(){

View File

@@ -0,0 +1,25 @@
App.Banners =
update_banner: (selector, text) ->
$(selector).html(text)
update_style: (selector, style) ->
$(selector).removeClass($(selector).attr("class"), true)
.addClass(style, true)
initialize: ->
$('[data-js-banner-title]').on
change: ->
App.Banners.update_banner("#js-banner-title", $(this).val())
$('[data-js-banner-description]').on
change: ->
App.Banners.update_banner("#js-banner-description", $(this).val())
$("#banner_style").on
change: ->
App.Banners.update_style("#js-banner-style", $(this).val())
$("#banner_image").on
change: ->
App.Banners.update_style("#js-banner-image", $(this).val())

View File

@@ -1,20 +1,22 @@
App.Votes = App.Votes =
hoverize: (votes) -> hoverize: (votes) ->
$(votes).hover -> $(document).on {
$("div.anonymous-votes", votes).show(); 'mouseenter focus': ->
$("div.organizations-votes", votes).show(); $("div.anonymous-votes", this).show();
$("div.not-logged", votes).show(); $("div.organizations-votes", this).show();
$("div.no-supports-allowed", votes).show(); $("div.not-logged", this).show();
$("div.logged", votes).hide(); $("div.no-supports-allowed", this).show();
, -> $("div.logged", this).hide();
$("div.anonymous-votes", votes).hide(); mouseleave: ->
$("div.organizations-votes", votes).hide(); $("div.anonymous-votes", this).hide();
$("div.not-logged", votes).hide(); $("div.organizations-votes", this).hide();
$("div.no-supports-allowed", votes).hide(); $("div.not-logged", this).hide();
$("div.logged", votes).show(); $("div.no-supports-allowed", this).hide();
$("div.logged", this).show();
}, votes
initialize: -> initialize: ->
App.Votes.hoverize votes for votes in $("div.votes") App.Votes.hoverize "div.votes"
App.Votes.hoverize votes for votes in $("div.supports") App.Votes.hoverize "div.supports"
false false

View File

@@ -3,6 +3,7 @@
// //
// Table of Contents: // Table of Contents:
// //
// 0. Custom variables
// 1. Global // 1. Global
// 2. Breakpoints // 2. Breakpoints
// 3. The Grid // 3. The Grid
@@ -43,6 +44,70 @@
@import 'util/util'; @import 'util/util';
// 0. Custom variables
// --------------------
$base-font-size: rem-calc(17);
$base-line-height: rem-calc(26);
$small-font-size: rem-calc(14);
$line-height: rem-calc(24);
$brand: #004A83;
$body: #E9E9E9;
$background: #EDEFF0;
$border: #DEE0E3;
$dark: darken($brand, 10%);
$text: #222222;
$text-medium: #999999;
$text-light: #CCCCCC;
$link: #2895F1;
$link-hover: #2178BF;
$debates: #008CCF;
$votes-bg: #26AEEE;
$votes-border: #1F94CB;
$votes-like: #7BD2A8;
$votes-like-act: #5D9E7F;
$votes-unlike: #EF8585;
$votes-unlike-act: #BD6A6A;
$delete: #F04124;
$check: #46DB91;
$proposals: #FFA42D;
$proposals-border: #CC8425;
$budget: #454372;
$budget-hover: #7571BF;
$highlight: #E7F2FC;
$featured: #FED900;
$footer-bg: #DEE0E2;
$footer-color: #171819;
$footer-link: #454A4C;
$footer-border: #BFC1C3;
$success-bg: #DFF0D8;
$success-border: #D6E9C6;
$color-success: #3C763D;
$info-bg: #D9EDF7;
$info-border: #BCE8F1;
$color-info: #31708F;
$warning-bg: #FCF8E3;
$warning-border: #FAEBCC;
$color-warning: #8A6D3B;
$alert-bg: #F2DEDE;
$alert-border: #EBCCD1;
$color-alert: #A94442;
// 1. Global // 1. Global
// --------- // ---------
@@ -127,7 +192,7 @@ $header-color: inherit;
$header-lineheight: 1.4; $header-lineheight: 1.4;
$header-margin-bottom: 0.5rem; $header-margin-bottom: 0.5rem;
$header-text-rendering: optimizeLegibility; $header-text-rendering: optimizeLegibility;
$small-font-size: 80%; $small-font-size: rem-calc(14);
$header-small-font-color: $medium-gray; $header-small-font-color: $medium-gray;
$paragraph-lineheight: 1.6; $paragraph-lineheight: 1.6;
$paragraph-margin-bottom: 1rem; $paragraph-margin-bottom: 1rem;
@@ -194,12 +259,12 @@ $input-error-font-weight: $global-weight-bold;
$accordion-background: $white; $accordion-background: $white;
$accordion-plusminus: true; $accordion-plusminus: true;
$accordion-item-color: foreground($accordion-background, $primary-color); $accordion-item-color: foreground($accordion-background, $text);
$accordion-item-background-hover: $light-gray; $accordion-item-background-hover: $light-gray;
$accordion-item-padding: 1.25rem 1rem; $accordion-item-padding: 1.25rem 1rem;
$accordion-content-background: $white; $accordion-content-background: $white;
$accordion-content-border: 1px solid $light-gray; $accordion-content-border: 1px solid $light-gray;
$accordion-content-color: foreground($accordion-background, $primary-color); $accordion-content-color: foreground($accordion-background, $text);
$accordion-content-padding: 1rem; $accordion-content-padding: 1rem;
// 8. Accordion Menu // 8. Accordion Menu
@@ -510,13 +575,13 @@ $show-header-for-stacked: false;
$tab-margin: 0; $tab-margin: 0;
$tab-background: $white; $tab-background: $white;
$tab-background-active: $light-gray; $tab-background-active: $white;
$tab-item-font-size: rem-calc(12); $tab-item-font-size: $base-font-size;
$tab-item-background-hover: $white; $tab-item-background-hover: $white;
$tab-item-padding: 1.25rem 1.5rem; $tab-item-padding: $line-height/2 0;
$tab-expand-max: 6; $tab-expand-max: 6;
$tab-content-background: $white; $tab-content-background: $white;
$tab-content-border: $light-gray; $tab-content-border: $border;
$tab-content-color: foreground($tab-background, $primary-color); $tab-content-color: foreground($tab-background, $primary-color);
$tab-content-padding: 1rem; $tab-content-padding: 1rem;
@@ -563,66 +628,3 @@ $topbar-submenu-background: $topbar-background;
$topbar-title-spacing: 1rem; $topbar-title-spacing: 1rem;
$topbar-input-width: 200px; $topbar-input-width: 200px;
$topbar-unstack-breakpoint: medium; $topbar-unstack-breakpoint: medium;
// 37. Custom variables
// --------------------
$base-font-size: rem-calc(17);
$base-line-height: rem-calc(26);
$small-font-size: rem-calc(14);
$line-height: rem-calc(24);
$brand: #004A83;
$body: #E9E9E9;
$background: #EDEFF0;
$border: #DEE0E3;
$dark: darken($brand, 10%);
$text: #222222;
$text-medium: #999999;
$text-light: #CCCCCC;
$link: #2895F1;
$link-hover: #2178BF;
$debates: #008CCF;
$votes-bg: #26AEEE;
$votes-border: #1F94CB;
$votes-like: #7BD2A8;
$votes-like-act: #5D9E7F;
$votes-unlike: #EF8585;
$votes-unlike-act: #BD6A6A;
$delete: #F04124;
$check: #46DB91;
$proposals: #FFA42D;
$proposals-border: #CC8425;
$budget: #454372;
$budget-hover: #7571BF;
$highlight: #E7F2FC;
$featured: #FED900;
$footer-bg: #DEE0E2;
$footer-color: #171819;
$footer-link: #454A4C;
$footer-border: #BFC1C3;
$success-bg: #DFF0D8;
$success-border: #D6E9C6;
$color-success: #3C763D;
$info-bg: #D9EDF7;
$info-border: #BCE8F1;
$color-info: #31708F;
$warning-bg: #FCF8E3;
$warning-border: #FAEBCC;
$color-warning: #8A6D3B;
$alert-bg: #F2DEDE;
$alert-border: #EBCCD1;
$color-alert: #A94442;

View File

@@ -8,67 +8,72 @@
// //
// 01. Global styles // 01. Global styles
// - - - - - - - - - - - - - - - - - - - - - - - - - // -----------------
$admin-color: #CF3638;
body.admin { body.admin {
header {
border: 0;
.top-links {
background: darken($admin-color, 15%);
}
}
.top-bar {
background: $admin-color !important;
height: auto;
}
form { form {
.button { .button {
margin-top: 0; margin-top: 0;
} }
input[type="text"], textarea { input[type="text"], textarea {
height: 48px\9;
line-height: 48px\9;
margin-bottom: 24px\9;
width: 100%; width: 100%;
} }
} }
table { table {
th {
text-align: left;
}
tr { tr {
background: #f4f4f4;
&:nth-child(odd) {
background: white; background: white;
} border: 1px solid $border;
&:nth-child(even) { &:hover {
background: #f0f0f0; background: #f3f6f7;
} }
} }
td.small { input[type="submit"] ~ a, a ~ a {
font-size: $small-font-size; margin-left: $line-height/2;
margin-right: $line-height/2;
} }
} }
hr {
max-width: none;
}
.menu.simple li.active {
border-bottom: 2px solid $admin-color;
color: $admin-color;
}
#proposals { #proposals {
width: 100% !important; width: 100% !important;
} }
.dashboard { .accordion-title {
margin-bottom: rem-calc(48); font-size: $base-font-size;
ul, ol {
margin-left: rem-calc(12);
li {
font-size: rem-calc(15);
line-height: rem-calc(30);
margin-bottom: rem-calc(12);
}
}
p {
font-size: rem-calc(15);
line-height: rem-calc(30);
}
h3 {
font-weight: bold;
}
} }
.button.secondary { .button.secondary {
@@ -99,17 +104,54 @@ body.admin {
display: none; display: none;
} }
.admin-content {
padding: $line-height !important;
}
@include breakpoint(medium) {
tr {
.on-hover-block {
display: none;
}
&:hover .on-hover-block {
display: block;
margin: 0;
margin-top: $line-height/2;
width: 100%;
}
}
}
@include breakpoint(medium) {
tr {
.on-hover {
display: none;
}
&:hover .on-hover {
display: inline;
}
}
}
// 02. Sidebar // 02. Sidebar
// - - - - - - - - - - - - - - - - - - - - - - - - - // -----------
.admin-sidebar { .admin-sidebar {
border-right: 1px solid $border;
a { @include breakpoint(medium) {
color: white\9 !important; padding-bottom: $line-height*3;
} }
ul { ul {
list-style-type: none; list-style-type: none;
margin-bottom: 0;
margin-left: 0; margin-left: 0;
padding: 0; padding: 0;
@@ -118,85 +160,44 @@ body.admin {
font-size: rem-calc(24); font-size: rem-calc(24);
padding-right: rem-calc(12); padding-right: rem-calc(12);
padding-top: rem-calc(4); padding-top: rem-calc(4);
padding-left: 12px\9 !important; vertical-align: middle;
padding-right: 12px\9 !important;
} }
li { li {
background: #2E343F; background: white;
border-bottom: 1px solid #292f39;
border-top: 1px solid #353c49;
margin: 0; margin: 0;
outline: 0; outline: 0;
&:first-child { &.active a {
background: #f3f6f7;
color: $admin-color;
font-weight: bold; font-weight: bold;
text-transform: uppercase;
}
&.active{
background: #373D47;
a:not(.button) {
color: white;
}
} }
} }
li a:not(.button) { li.section {
color: rgba(255,255,255,0.3); border-bottom: 1px dotted #d5d5d5;
border-top: 1px dotted #d5d5d5;
height: $line-height/2;
}
li a {
color: $text;
display: block;
line-height: rem-calc(48); line-height: rem-calc(48);
padding-left: rem-calc(12); padding-left: rem-calc(12);
vertical-align: top; vertical-align: top;
&:hover { &:hover {
color: white; background: #f3f6f7;
text-decoration: none;
} }
} }
} }
} }
// 03. List elements // 03. List elements
// - - - - - - - - - - - - - - - - - - - - - - - - - // -----------------
.admin-list {
list-style-type: none;
margin: 0;
margin-bottom: rem-calc(48);
form {
clear: both;
.checkbox {
font-size: $small-font-size;
}
}
li {
border-bottom: 1px solid #E7E9EC;
font-size: rem-calc(14);
min-height: rem-calc(72);
padding: rem-calc(12);
&:first-child {
border-top: 1px solid #E7E9EC;
}
&:nth-child(odd) {
background: #F0F2F6;
}
}
.tag {
float: left;
font-size: rem-calc(18);
padding: 0;
}
.button {
margin: 0;
}
}
.delete { .delete {
border-bottom: 1px dotted #CF2A0E; border-bottom: 1px dotted #CF2A0E;
@@ -239,14 +240,9 @@ body.admin {
font-style: italic; font-style: italic;
} }
.level {
font-size: rem-calc(12);
}
.official { .official {
background-color: #e7e7e7; background-color: #e7e7e7;
border-radius: rem-calc(3); border-radius: rem-calc(3);
font-size: rem-calc(12);
font-weight: normal; font-weight: normal;
padding: rem-calc(6) rem-calc(12); padding: rem-calc(6) rem-calc(12);
} }
@@ -262,13 +258,10 @@ body.admin {
.moderation-description { .moderation-description {
max-height: rem-calc(65); max-height: rem-calc(65);
overflow: hidden; overflow: hidden;
max-width: rem-calc(590); max-width: rem-calc(700);
&:hover { &:hover {
cursor: text;
max-height: rem-calc(1000); max-height: rem-calc(1000);
outline: 3px solid #ffbf47;
padding: rem-calc(12);
transition: max-height 0.9s; transition: max-height 0.9s;
-moz-transition: max-height 0.9s; -moz-transition: max-height 0.9s;
-webkit-transition: max-height 0.9s; -webkit-transition: max-height 0.9s;
@@ -276,7 +269,7 @@ body.admin {
} }
// 04. Stats // 04. Stats
// - - - - - - - - - - - - - - - - - - - - - - - - - // ---------
.stats { .stats {
background: white; background: white;
@@ -304,7 +297,7 @@ body.admin {
} }
// 05. Management // 05. Management
// - - - - - - - - - - - - - - - - - - - - - - - - - // --------------
.user-permissions { .user-permissions {
@@ -337,8 +330,8 @@ body.admin {
border-radius: rem-calc(3); border-radius: rem-calc(3);
font-size: rem-calc(16); font-size: rem-calc(16);
font-weight: normal; font-weight: normal;
margin-bottom: rem-calc(12); margin: $line-height;
padding: rem-calc(6) rem-calc(12); padding: $line-height/2;
strong { strong {
font-size: rem-calc(18); font-size: rem-calc(18);

View File

@@ -51,7 +51,7 @@
border-right: 1px solid $dark; border-right: 1px solid $dark;
tr th { tr th {
color: white; color: $dark;
} }
} }

View File

@@ -0,0 +1,199 @@
// Stylesheet for Internet Explorer
//
// Table of Contents
// 01. Global styles
// 02. Admin
//
// 01. Global styles
// -----------------
*, *:before, *:after {
box-sizing: border-box !important;
}
.show-for-medium-down,
.show-for-medium,
.show-for-small {
display: none !important;
}
.show-for-large-up,
.hide-for-medium-down {
display: block !important;
}
.column, .columns {
display: inline-block !important;
float: none !important;
box-sizing: border-box !important;
}
.small-1, .row .small-1 { width: 7.33333%; }
.small-2, .row .small-2 { width: 15.66667%; }
.small-3, .row .small-3 { width: 24%; }
.small-4, .row .small-4 { width: 32.33333%; }
.small-5, .row .small-5 { width: 40.66667%; }
.small-6, .row .small-6 { width: 49%; }
.small-7, .row .small-7 { width: 57.33333%; }
.small-8, .row .small-8 { width: 65.66667%; }
.small-9, .row .small-9 { width: 74%; }
.small-10, .row .small-10 { width: 82.33333%; }
.small-11, .row .small-11 { width: 90.66667%; }
.small-12, .row .small-12 { width: 99%; }
.medium-1, .row .medium-1 { width: 7.33333%; }
.medium-2, .row .medium-2 { width: 15.66667%; }
.medium-3, .row .medium-3 { width: 24%; }
.medium-4, .row .medium-4 { width: 32.33333%; }
.medium-5, .row .medium-5 { width: 40.66667%; }
.medium-6, .row .medium-6 { width: 49%; }
.medium-7, .row .medium-7 { width: 57.33333%; }
.medium-8, .row .medium-8 { width: 65.66667%; }
.medium-9, .row .medium-9 { width: 74%; }
.medium-10, .row .medium-10 { width: 82.33333%; }
.medium-11, .row .medium-11 { width: 90.66667%; }
.medium-12, .row .medium-12 { width: 99%; }
.large-1, .row .large-1 { width: 7.33333%; }
.large-2, .row .large-2 { width: 15.66667%; }
.large-3, .row .large-3 { width: 24%; }
.large-4, .row .large-4 { width: 32.33333%; }
.large-5, .row .large-5 { width: 40.66667%; }
.large-6, .row .large-6 { width: 49%; }
.large-7, .row .large-7 { width: 57.33333%; }
.large-8, .row .large-8 { width: 65.66667%; }
.large-9, .row .large-9 { width: 74%; }
.large-10, .row .large-10 { width: 82.33333%; }
.large-11, .row .large-11 { width: 90.66667%; }
.large-12, .row .large-12 { width: 99%; }
.row .small-offset-1 { margin-left: 7.33333%; }
.row .small-offset-2 { margin-left: 15.66667%; }
.row .small-offset-3 { margin-left: 24%; }
.row .small-offset-4 { margin-left: 32.33333%; }
.row .small-offset-5 { margin-left: 40.66667%; }
.row .small-offset-6 { margin-left: 49%; }
.row .small-offset-7 { margin-left: 57.33333%; }
.row .small-offset-8 { margin-left: 65.66667%; }
.row .small-offset-9 { margin-left: 74%; }
.row .small-offset-10 { margin-left: 82.33333%; }
.row .small-offset-11 { margin-left: 90.66667%; }
.row .small-offset-12 { margin-left: 99%; }
.row .medium-offset-1 { margin-left: 7.33333%; }
.row .medium-offset-2 { margin-left: 15.66667%; }
.row .medium-offset-3 { margin-left: 24%; }
.row .medium-offset-4 { margin-left: 32.33333%; }
.row .medium-offset-5 { margin-left: 40.66667%; }
.row .medium-offset-6 { margin-left: 49%; }
.row .medium-offset-7 { margin-left: 57.33333%; }
.row .medium-offset-8 { margin-left: 65.66667%; }
.row .medium-offset-9 { margin-left: 74%; }
.row .medium-offset-10 { margin-left: 82.33333%; }
.row .medium-offset-11 { margin-left: 90.66667%; }
.row .medium-offset-12 { margin-left: 99%; }
.row .large-offset-1 { margin-left: 7.33333%; }
.row .large-offset-2 { margin-left: 15.66667%; }
.row .large-offset-3 { margin-left: 24%; }
.row .large-offset-4 { margin-left: 32.33333%; }
.row .large-offset-5 { margin-left: 40.66667%; }
.row .large-offset-6 { margin-left: 49%; }
.row .large-offset-7 { margin-left: 57.33333%; }
.row .large-offset-8 { margin-left: 65.66667%; }
.row .large-offset-9 { margin-left: 74%; }
.row .large-offset-10 { margin-left: 82.33333%; }
.row .large-offset-11 { margin-left: 90.66667%; }
.row .large-offset-12 { margin-left: 99%; }
.top-bar {
clear: both !important;
height: 100px !important;
}
.locale, .external-links {
background: #002d50 !important;
}
.locale {
float: left !important;
}
.external-links {
color: white !important;
float: right !important;
}
.top-bar-title, .top-bar-title a, .top-bar-title a {
display: inline-block !important;
float: none !important;
}
.top-bar-title a {
line-height: 24px !important;
width: 100% !important;
}
.proposal .supports {
display: inline-block !important;
margin: 0 !important;
position: inherit !important;
&:after {
content: none !important;
}
}
form {
input, textarea {
height: 48px !important;
line-height: 48px !important;
margin-bottom: 24px !important;
width: 100% !important;
}
input[type="checkbox"],
input[type="radio"] {
height: auto !important;
line-height: inherit !important;
width: auto !important;
}
input[type="radio"] {
width: 18px !important;
}
}
.subnavigation {
display: block;
height: 60px !important;
width: 100%;
ul li a {
margin-left: 10px !important;
margin-right: 10px !important;
}
}
.truncate {
background: none;
}
// 02. Admin
// ---------
body.admin form {
input[type="text"], textarea {
height: 48px !important;
line-height: 48px !important;
margin-bottom: 24px !important;
}
}
.admin-sidebar ul [class^="icon-"] {
padding-left: 12px !important;
padding-right: 12px !important;
}

View File

@@ -17,6 +17,7 @@
// 15. Comments // 15. Comments
// 16. Flags // 16. Flags
// 17. Activity // 17. Activity
// 18. Banners
// //
// 01. Global styles // 01. Global styles
@@ -218,9 +219,48 @@ a {
float: left; float: left;
} }
.table-fixed { //<<<<<<< HEAD
table-layout: fixed; //.table-fixed {
} // table-layout: fixed;
//=======
//.tabs-content {
// border: 0;
//}
//
//.tabs {
// border: {
// left: 0;
// right: 0;
// top: 0;
// };
// margin-bottom: $line-height;
//
// .tabs-title > a {
// color: $text-medium;
// margin-bottom: rem-calc(-1);
// margin-right: $line-height;
//
// &[aria-selected='true'],
// &.is-active {
// color: $brand;
// border-bottom: 2px solid $brand;
// font-weight: bold;
// }
// }
//
// h2 {
// font-size: $base-font-size;
// }
//}
//
//.no-max-width {
// max-width: none;
//}
//
//.button.float-right ~ .button.float-right {
// margin: 0 $line-height/2;
//>>>>>>> budget
//}
// 02. Header // 02. Header
// ---------- // ----------
@@ -361,8 +401,6 @@ header {
color: $text; color: $text;
display: block; display: block;
font-weight: bold; font-weight: bold;
margin-left: 18px\9;
margin-right: 18px\9;
width: auto; width: auto;
&:hover { &:hover {
@@ -636,24 +674,9 @@ form {
font-weight: bold; font-weight: bold;
} }
input, textarea {
height: 48px\9;
line-height: 48px\9;
margin-bottom: 24px\9;
width: 100%\9;
}
input[type="checkbox"],
input[type="radio"] {
height: auto\9;
line-height: inherit\9;
width: auto\9;
}
input[type="radio"] { input[type="radio"] {
height: $line-height !important; height: $line-height !important;
vertical-align: top; vertical-align: top;
width: 18px\9;
+ label { + label {
font-weight: normal; font-weight: normal;
@@ -1067,12 +1090,13 @@ table {
} }
} }
.social-share-button-twitter { .ssb-twitter {
background: #45B0E3; background: #45B0E3;
background-image: none !important;
color: white; color: white;
height: $line-height*2; height: $line-height*2 !important;
position: relative; position: relative;
width: $line-height*2; width: $line-height*2 !important;
&:before { &:before {
content: "f"; content: "f";
@@ -1106,12 +1130,13 @@ table {
} }
} }
.social-share-button-facebook { .ssb-facebook {
background: #3B5998; background: #3B5998;
background-image: none !important;
color: white; color: white;
height: rem-calc(48); height: rem-calc(48) !important;
position: relative; position: relative;
width: rem-calc(48); width: rem-calc(48) !important;
&:before { &:before {
content: "A"; content: "A";
@@ -1145,12 +1170,13 @@ table {
} }
} }
.social-share-button-google_plus { .ssb-google_plus {
background: #DE4C34; background: #DE4C34;
background-image: none !important;
color: white; color: white;
height: $line-height*2; height: $line-height*2 !important;
position: relative; position: relative;
width: $line-height*2; width: $line-height*2 !important;
&:before { &:before {
content: "B"; content: "B";
@@ -1188,7 +1214,7 @@ table {
display: inline-block; display: inline-block;
} }
.social-share-button-twitter { .ssb-twitter {
background: none; background: none;
color: white; color: white;
height: $line-height; height: $line-height;
@@ -1211,7 +1237,7 @@ table {
} }
} }
.social-share-button-facebook { .ssb-facebook {
background: none; background: none;
color: white; color: white;
height: rem-calc(24); height: rem-calc(24);
@@ -1234,7 +1260,7 @@ table {
} }
} }
.social-share-button-google_plus { .ssb-google_plus {
background: none; background: none;
color: white; color: white;
height: rem-calc(24); height: rem-calc(24);
@@ -1463,7 +1489,6 @@ table {
.comments { .comments {
background: $white; background: $white;
background-repeat: repeat-x; background-repeat: repeat-x;
padding-top: $line-height;
padding-bottom: $line-height*4; padding-bottom: $line-height*4;
h2 { h2 {
@@ -1487,7 +1512,7 @@ table {
.comment-votes { .comment-votes {
color: $text-medium; color: $text-medium;
font-size: $small-font-size; font-size: rem-calc(14);
line-height: $line-height; line-height: $line-height;
a { a {
@@ -1650,7 +1675,7 @@ table {
&:first-child { &:first-child {
padding-left: $line-height*1.5; padding-left: $line-height*1.5;
width: 80%; width: 75%;
} }
&:before { &:before {
@@ -1690,3 +1715,69 @@ table {
} }
} }
} }
// 18. Banners
// -----------
.banner-style-one {
background-color: $brand;
}
.banner-style-two {
background-color: $budget;
}
.banner-style-three {
background-color: #33DADF;
}
@include breakpoint(large) {
.banner-img-one {
background-image: image-url('banners/banner1.png');
}
.banner-img-two {
background-image: image-url('banners/banner2.png');
}
.banner-img-three {
background-image: image-url('banners/banner3.png');
}
}
.banner-img-one, .banner-img-two, .banner-img-three {
background-position: bottom right;
background-repeat: no-repeat;
}
.banner-style-one, .banner-style-two, .banner-style-three {
margin: 0;
margin-bottom: $line-height;
h2, h3, a {
color: #eaeaf2;
}
h2 {
padding: $line-height/2;
padding-bottom: 0;
}
h3 {
padding: $line-height/2;
padding-top: 0;
}
a:hover h2, a:hover h3 {
color: #eaeaf2 !important;
text-decoration: none;
}
@include breakpoint(large) {
h3 {
width: 80%;
}
}
}

View File

@@ -8,6 +8,7 @@
@mixin logo { @mixin logo {
color: white; color: white;
display: inline-block;
font-family: 'Lato' !important; font-family: 'Lato' !important;
font-size: rem-calc(24); font-size: rem-calc(24);
font-weight: lighter; font-weight: lighter;

View File

@@ -720,6 +720,16 @@
} }
} }
.more-info {
clear: both;
color: $text-medium;
font-size: $small-font-size;
a {
color: $text-medium;
}
}
.debate { .debate {
.votes { .votes {
@@ -897,9 +907,9 @@
.share-supported { .share-supported {
.social-share-button-twitter, .ssb-twitter,
.social-share-button-facebook, .ssb-facebook,
.social-share-button-google_plus { .ssb-google_plus {
color: $budget; color: $budget;
} }
} }
@@ -1016,9 +1026,9 @@
.share-supported { .share-supported {
.social-share-button-twitter, .ssb-twitter,
.social-share-button-facebook, .ssb-facebook,
.social-share-button-google_plus { .ssb-google_plus {
height: rem-calc(33); height: rem-calc(33);
&:before { &:before {

View File

@@ -12,6 +12,8 @@
#print_link { display: none !important; } #print_link { display: none !important; }
#responsive-menu { display: none !important; }
.admin-sidebar { display: none !important; } .admin-sidebar { display: none !important; }
img.left { display: none !important; } img.left { display: none !important; }

View File

@@ -25,7 +25,7 @@ class AccountController < ApplicationController
if @account.organization? if @account.organization?
params.require(:account).permit(:phone_number, :email_on_comment, :email_on_comment_reply, :newsletter, organization_attributes: [:name, :responsible_name]) params.require(:account).permit(:phone_number, :email_on_comment, :email_on_comment_reply, :newsletter, organization_attributes: [:name, :responsible_name])
else else
params.require(:account).permit(:username, :public_activity, :email_on_comment, :email_on_comment_reply, :newsletter) params.require(:account).permit(:username, :public_activity, :email_on_comment, :email_on_comment_reply, :email_on_direct_message, :email_digest, :newsletter, :official_position_badge)
end end
end end

View File

@@ -0,0 +1,56 @@
class Admin::BannersController < Admin::BaseController
has_filters %w{all with_active with_inactive}, only: :index
before_action :find_banner, only: [:edit, :update, :destroy]
before_action :banner_styles, only: [:edit, :new, :create, :update]
before_action :banner_imgs, only: [:edit, :new, :create, :update]
respond_to :html, :js
load_and_authorize_resource
def index
@banners = Banner.send(@current_filter).page(params[:page])
end
def create
@banner = Banner.new(banner_params)
if @banner.save
redirect_to admin_banners_path
else
render :new
end
end
def update
@banner.assign_attributes(banner_params)
if @banner.update(banner_params)
redirect_to admin_banners_path
else
render :edit
end
end
def destroy
@banner.destroy
redirect_to admin_banners_path
end
private
def banner_params
params.require(:banner).permit(:title, :description, :target_url, :style, :image, :post_started_at, :post_ended_at)
end
def find_banner
@banner = Banner.find(params[:id])
end
def banner_styles
@banner_styles = Setting.all.banner_style.map { |banner_style| [banner_style.value, banner_style.key.split('.')[1]] }
end
def banner_imgs
@banner_imgs = Setting.all.banner_img.map { |banner_img| [banner_img.value, banner_img.key.split('.')[1]] }
end
end

View File

@@ -1,9 +1,11 @@
class Admin::SettingsController < Admin::BaseController class Admin::SettingsController < Admin::BaseController
def index def index
all_settings = (Setting.all).group_by { |s| s.feature_flag? } all_settings = (Setting.all).group_by { |s| s.type }
@settings = all_settings[false] @settings = all_settings['common']
@feature_flags = all_settings[true] @feature_flags = all_settings['feature']
@banner_styles = all_settings['banner-style']
@banner_imgs = all_settings['banner-img']
end end
def update def update

View File

@@ -21,6 +21,15 @@ class Admin::StatsController < Admin::BaseController
@user_ids_who_voted_proposals = ActsAsVotable::Vote.where(votable_type: 'Proposal').distinct.count(:voter_id) @user_ids_who_voted_proposals = ActsAsVotable::Vote.where(votable_type: 'Proposal').distinct.count(:voter_id)
@user_ids_who_didnt_vote_proposals = @verified_users - @user_ids_who_voted_proposals @user_ids_who_didnt_vote_proposals = @verified_users - @user_ids_who_voted_proposals
@spending_proposals = SpendingProposal.count @spending_proposals = SpendingProposal.count
end
def proposal_notifications
@proposal_notifications = ProposalNotification.all
@proposals_with_notifications = @proposal_notifications.select(:proposal_id).distinct.count
end
def direct_messages
@direct_messages = DirectMessage.count
@users_who_have_sent_message = DirectMessage.select(:sender_id).distinct.count
end end
end end

View File

@@ -0,0 +1,10 @@
class Budget
class BudgetsController < ApplicationController
load_and_authorize_resource
def index
@budgets = Budget.all
end
end
end

View File

@@ -0,0 +1,85 @@
class Budget
class InvestmentsController < ApplicationController
include FeatureFlags
before_action :load_investments, only: [:index]
before_action :load_geozone, only: [:index, :unfeasible]
skip_authorization_check
before_action :authenticate_user!, except: [:index, :show]
before_action -> { flash.now[:notice] = flash[:notice].html_safe if flash[:html_safe] && flash[:notice] }
load_and_authorize_resource
feature_flag :spending_proposals
invisible_captcha only: [:create, :update], honeypot: :subtitle
respond_to :html, :js
def index
load_investments
set_spending_proposal_votes(@investments)
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
if @spending_proposal.save
notice = t('flash.actions.create.spending_proposal', activity: "<a href='#{user_path(current_user, filter: :spending_proposals)}'>#{t('layouts.header.my_activity_link')}</a>")
redirect_to @spending_proposal, notice: notice, flash: { html_safe: true }
else
render :new
end
end
def destroy
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)
end
def load_investments
@investments = filter_and_search(Budget::Investment)
end
def filter_and_search(target)
target = target.unfeasible if params[:unfeasible].present?
target = target.by_geozone(params[:geozone]) if params[:geozone].present?
target = target.search(params[:search]) if params[:search].present?
target.page(params[:page]).for_render
end
def load_geozone
return if params[:geozone].blank?
if params[:geozone] == 'all'
@geozone_name = t('geozones.none')
else
@geozone_name = Geozone.find(params[:geozone]).name
end
end
end
end

View File

@@ -11,6 +11,8 @@ module CommentableActions
index_customization if index_customization.present? index_customization if index_customization.present?
@tag_cloud = tag_cloud @tag_cloud = tag_cloud
@banners = Banner.with_active
set_resource_votes(@resources) set_resource_votes(@resources)
set_resources_instance set_resources_instance
end end

View File

@@ -3,7 +3,7 @@ module FeatureFlags
class_methods do class_methods do
def feature_flag(name, *options) def feature_flag(name, *options)
before_filter(*options) do before_action(*options) do
check_feature_flag(name) check_feature_flag(name)
end end
end end

View File

@@ -0,0 +1,36 @@
class DirectMessagesController < ApplicationController
load_and_authorize_resource
def new
@receiver = User.find(params[:user_id])
@direct_message = DirectMessage.new(receiver: @receiver)
end
def create
@sender = current_user
@receiver = User.find(params[:user_id])
@direct_message = DirectMessage.new(parsed_params)
if @direct_message.save
Mailer.direct_message_for_receiver(@direct_message).deliver_later
Mailer.direct_message_for_sender(@direct_message).deliver_later
redirect_to [@receiver, @direct_message], notice: I18n.t("flash.actions.create.direct_message")
else
render :new
end
end
def show
@direct_message = DirectMessage.find(params[:id])
end
private
def direct_message_params
params.require(:direct_message).permit(:title, :body)
end
def parsed_params
direct_message_params.merge(sender: @sender, receiver: @receiver)
end
end

View File

@@ -13,6 +13,7 @@ class Management::ProposalsController < Management::BaseController
def show def show
super super
@notifications = @proposal.notifications
redirect_to management_proposal_path(@proposal), status: :moved_permanently if request.path != management_proposal_path(@proposal) redirect_to management_proposal_path(@proposal), status: :moved_permanently if request.path != management_proposal_path(@proposal)
end end

View File

@@ -0,0 +1,13 @@
class Management::UserInvitesController < Management::BaseController
def new
end
def create
@emails = params[:emails].split(",").map(&:strip)
@emails.each do |email|
Mailer.user_invite(email).deliver_later
end
end
end

View File

@@ -9,7 +9,7 @@ class NotificationsController < ApplicationController
def show def show
@notification = current_user.notifications.find(params[:id]) @notification = current_user.notifications.find(params[:id])
redirect_to url_for(@notification.notifiable) redirect_to url_for(@notification.linkable_resource)
end end
def mark_all_as_read def mark_all_as_read

View File

@@ -0,0 +1,33 @@
class ProposalNotificationsController < ApplicationController
load_and_authorize_resource except: [:new]
def new
@proposal = Proposal.find(params[:proposal_id])
@notification = ProposalNotification.new(proposal_id: @proposal.id)
authorize! :new, @notification
end
def create
@notification = ProposalNotification.new(proposal_notification_params)
@proposal = Proposal.find(proposal_notification_params[:proposal_id])
if @notification.save
@proposal.voters.each do |voter|
Notification.add(voter.id, @notification)
end
redirect_to @notification, notice: I18n.t("flash.actions.create.proposal_notification")
else
render :new
end
end
def show
@notification = ProposalNotification.find(params[:id])
end
private
def proposal_notification_params
params.require(:proposal_notification).permit(:title, :body, :proposal_id)
end
end

View File

@@ -2,7 +2,6 @@ class ProposalsController < ApplicationController
include CommentableActions include CommentableActions
include FlagActions include FlagActions
before_action :parse_search_terms, only: [:index, :suggest] before_action :parse_search_terms, only: [:index, :suggest]
before_action :parse_advanced_search_terms, only: :index before_action :parse_advanced_search_terms, only: :index
before_action :parse_tag_filter, only: :index before_action :parse_tag_filter, only: :index
@@ -22,6 +21,7 @@ class ProposalsController < ApplicationController
def show def show
super super
@notifications = @proposal.notifications
redirect_to proposal_path(@proposal), status: :moved_permanently if request.path != proposal_path(@proposal) redirect_to proposal_path(@proposal), status: :moved_permanently if request.path != proposal_path(@proposal)
end end

View File

@@ -1,7 +1,7 @@
class SpendingProposalsController < ApplicationController class SpendingProposalsController < ApplicationController
include FeatureFlags include FeatureFlags
before_action :authenticate_user!, except: [:index] before_action :authenticate_user!, except: [:index, :show]
before_action -> { 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 load_and_authorize_resource

View File

@@ -3,6 +3,7 @@ class UsersController < ApplicationController
load_and_authorize_resource load_and_authorize_resource
helper_method :authorized_for_filter? helper_method :authorized_for_filter?
helper_method :author?
helper_method :author_or_admin? helper_method :author_or_admin?
def show def show
@@ -65,8 +66,12 @@ class UsersController < ApplicationController
@user.public_activity || authorized_current_user? @user.public_activity || authorized_current_user?
end end
def author?
@author ||= current_user && (current_user == @user)
end
def author_or_admin? def author_or_admin?
@author_or_admin ||= current_user && (current_user == @user || current_user.administrator?) @author_or_admin ||= current_user && (author? || current_user.administrator?)
end end
def authorized_current_user? def authorized_current_user?

View File

@@ -35,4 +35,9 @@ module ApplicationHelper
} }
Redcarpet::Markdown.new(renderer, extensions).render(text).html_safe Redcarpet::Markdown.new(renderer, extensions).render(text).html_safe
end end
def author_of?(authorable, user)
return false if authorable.blank? || user.blank?
authorable.author_id == user.id
end
end end

View File

@@ -0,0 +1,5 @@
module BannersHelper
def has_banners
@banners.count > 0
end
end

View File

@@ -1,6 +1,4 @@
module NotificationsHelper module NotificationsHelper
def notification_action(notification)
notification.notifiable_type == "Comment" ? "replies_to" : "comments_on"
end
end end

View File

@@ -1,5 +1,5 @@
class ApplicationMailer < ActionMailer::Base class ApplicationMailer < ActionMailer::Base
helper :settings helper :settings
default from: "participacion@madrid.es" default from: "Consul <no-reply@consul.es>"
layout 'mailer' layout 'mailer'
end end

View File

@@ -42,6 +42,38 @@ class Mailer < ApplicationMailer
end end
end end
def direct_message_for_receiver(direct_message)
@direct_message = direct_message
@receiver = @direct_message.receiver
with_user(@receiver) do
mail(to: @receiver.email, subject: t('mailers.direct_message_for_receiver.subject'))
end
end
def direct_message_for_sender(direct_message)
@direct_message = direct_message
@sender = @direct_message.sender
with_user(@sender) do
mail(to: @sender.email, subject: t('mailers.direct_message_for_sender.subject'))
end
end
def proposal_notification_digest(user)
@notifications = user.notifications.where(notifiable_type: "ProposalNotification")
with_user(user) do
mail(to: user.email, subject: t('mailers.proposal_notification_digest.title', org_name: Setting['org_name']))
end
end
def user_invite(email)
I18n.with_locale(I18n.default_locale) do
mail(to: email, subject: t('mailers.user_invite.subject', org_name: Setting["org_name"]))
end
end
private private
def with_user(user, &block) def with_user(user, &block)

View File

@@ -46,6 +46,8 @@ module Abilities
can [:hide, :update], Budget::Investment can [:hide, :update], Budget::Investment
can :valuate, Budget::Investment, budget: { valuating: true } can :valuate, Budget::Investment, budget: { valuating: true }
can :create, Budget::ValuatorAssignment can :create, Budget::ValuatorAssignment
can [:search, :edit, :update, :create, :index, :destroy], Banner
end end
end end
end end

View File

@@ -44,14 +44,19 @@ module Abilities
can :vote_featured, Proposal can :vote_featured, Proposal
can :vote, SpendingProposal can :vote, SpendingProposal
can :create, SpendingProposal can :create, SpendingProposal
can :create, Budget::Investment, budget: { phase: "accepting" } can :create, Budget::Investment, budget: { phase: "accepting" }
can :vote, Budget::Investment, budget: { phase: "selecting" } can :vote, Budget::Investment, budget: { phase: "selecting" }
can :create, Budget::Ballot, budget: { phase: "balloting" } can :create, Budget::Ballot, budget: { phase: "balloting" }
can :create, DirectMessage
can :show, DirectMessage, sender_id: user.id
end end
can [:create, :show], ProposalNotification, proposal: { author_id: user.id }
can :create, Annotation can :create, Annotation
can [:update, :destroy], Annotation, user_id: user.id can [:update, :destroy], Annotation, user_id: user.id
end end
end end
end end

View File

@@ -12,6 +12,9 @@ module Abilities
can :read, Legislation can :read, Legislation
can :read, User can :read, User
can [:search, :read], Annotation can [:search, :read], Annotation
can [:read], Budget
can [:read], Budget::Investment
can :new, DirectMessage
end end
end end
end end

20
app/models/banner.rb Normal file
View File

@@ -0,0 +1,20 @@
class Banner < ActiveRecord::Base
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
validates :title, presence: true,
length: { minimum: 2 }
validates :description, presence: true
validates :target_url, presence: true
validates :style, presence: true
validates :image, presence: true
validates :post_started_at, presence: true
validates :post_ended_at, presence: true
scope :with_active, -> {where("post_started_at <= ?", Time.now).
where("post_ended_at >= ?", Time.now) }
scope :with_inactive,-> {where("post_started_at > ? or post_ended_at < ?", Time.now, Time.now) }
end

View File

@@ -7,9 +7,11 @@ class Budget < ActiveRecord::Base
validates :phase, inclusion: { in: VALID_PHASES } validates :phase, inclusion: { in: VALID_PHASES }
validates :currency_symbol, presence: true validates :currency_symbol, presence: true
has_many :investments has_many :investments, dependent: :destroy
has_many :ballots has_many :ballots, dependent: :destroy
has_many :headings has_many :groups, dependent: :destroy
has_many :headings, through: :groups
has_many :investments, through: :headings
def on_hold? def on_hold?
phase == "on_hold" phase == "on_hold"
@@ -32,7 +34,6 @@ class Budget < ActiveRecord::Base
end end
def heading_price(heading) def heading_price(heading)
return price unless heading.present?
heading_ids.include?(heading.id) ? heading.price : -1 heading_ids.include?(heading.id) ? heading.price : -1
end end
end end

View File

@@ -2,11 +2,14 @@ class Budget
class Ballot < ActiveRecord::Base class Ballot < ActiveRecord::Base
belongs_to :user belongs_to :user
belongs_to :budget belongs_to :budget
belongs_to :heading
has_many :lines, dependent: :destroy has_many :lines, dependent: :destroy
has_many :investments, through: :lines has_many :investments, through: :lines
def add_investment(investment)
lines.create!(budget: budget, investment: investment, heading: investment.heading, group_id: investment.heading.group_id)
end
def total_amount_spent def total_amount_spent
investments.sum(:price).to_i investments.sum(:price).to_i
end end
@@ -16,7 +19,17 @@ class Budget
end end
def amount_available(heading) def amount_available(heading)
budget.heading_price(heading) - amount_spent(heading.try(:id)) budget.heading_price(heading) - amount_spent(heading.id)
end
def valid_heading?(heading)
group = heading.group
return false if group.budget_id != budget_id
line = lines.where(heading_id: group.heading_ids).first
return false if line.present? && line.heading_id != heading.id
true
end end
def has_lines_with_no_heading? def has_lines_with_no_heading?

View File

@@ -2,11 +2,15 @@ class Budget
class Ballot class Ballot
class Line < ActiveRecord::Base class Line < ActiveRecord::Base
belongs_to :ballot belongs_to :ballot
belongs_to :budget
belongs_to :group
belongs_to :heading
belongs_to :investment belongs_to :investment
validate :insufficient_funds validate :insufficient_funds
validate :different_geozone, :if => :district_proposal? validate :different_geozone, :if => :district_proposal?
validate :unfeasible validate :unfeasible
#needed? validates :ballot_id, :budget_id, :group_id, :heading_id, :investment_id, presence: true
def insufficient_funds def insufficient_funds
errors.add(:money, "") if ballot.amount_available(investment.heading) < investment.price.to_i errors.add(:money, "") if ballot.amount_available(investment.heading) < investment.price.to_i
@@ -23,7 +27,6 @@ class Budget
def heading_proposal? def heading_proposal?
investment.heading_id.present? investment.heading_id.present?
end end
end end
end end
end end

View File

@@ -0,0 +1,10 @@
class Budget
class Group < ActiveRecord::Base
belongs_to :budget
has_many :headings, dependent: :destroy
validates :budget_id, presence: true
validates :name, presence: true
end
end

View File

@@ -1,11 +1,11 @@
class Budget class Budget
class Heading < ActiveRecord::Base class Heading < ActiveRecord::Base
belongs_to :budget belongs_to :group
belongs_to :geozone belongs_to :geozone
has_many :investments has_many :investments
validates :budget_id, presence: true validates :group_id, presence: true
validates :name, presence: true validates :name, presence: true
validates :price, presence: true validates :price, presence: true
end end

View File

@@ -10,7 +10,6 @@ class Budget
acts_as_paranoid column: :hidden_at acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases include ActsAsParanoidAliases
belongs_to :budget
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :heading belongs_to :heading
belongs_to :administrator belongs_to :administrator
@@ -22,6 +21,7 @@ class Budget
validates :title, presence: true validates :title, presence: true
validates :author, presence: true validates :author, presence: true
validates :description, presence: true validates :description, presence: true
validates :heading_id, presence: true
validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required? validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required?
validates :title, length: { in: 4 .. Budget::Investment.title_max_length } validates :title, length: { in: 4 .. Budget::Investment.title_max_length }
@@ -44,16 +44,12 @@ class Budget
scope :with_supports, -> { where('cached_votes_up > 0') } scope :with_supports, -> { where('cached_votes_up > 0') }
scope :by_heading, -> (heading_id) { where(heading_id: heading_id) } scope :by_heading, -> (heading_id) { where(heading_id: heading_id) }
scope :by_budget, -> (budget_id) { where(budget_id: budget_id) }
scope :by_admin, -> (admin_id) { where(administrator_id: admin_id) } scope :by_admin, -> (admin_id) { where(administrator_id: admin_id) }
scope :by_tag, -> (tag_name) { tagged_with(tag_name) } scope :by_tag, -> (tag_name) { tagged_with(tag_name) }
scope :by_valuator, -> (valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) } scope :by_valuator, -> (valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) }
scope :for_render, -> { includes(heading: :geozone) } scope :for_render, -> { includes(heading: :geozone) }
scope :with_heading, -> { where.not(heading_id: nil) }
scope :no_heading, -> { where(heading_id: nil) }
before_save :calculate_confidence_score before_save :calculate_confidence_score
before_validation :set_responsible_name before_validation :set_responsible_name
@@ -62,8 +58,7 @@ class Budget
end end
def self.scoped_filter(params, current_filter) def self.scoped_filter(params, current_filter)
budget = Budget.find!(params[:budget_id]) results = budget.investments
results = self.by_budget(params[:budget_id])
if params[:max_for_no_heading].present? || params[:max_per_heading].present? if params[:max_for_no_heading].present? || params[:max_per_heading].present?
results = limit_results(results, budget, params[:max_per_heading].to_i, params[:max_for_no_heading].to_i) results = limit_results(results, budget, params[:max_per_heading].to_i, params[:max_for_no_heading].to_i)
end end
@@ -119,6 +114,10 @@ class Budget
where(heading_id: heading == 'all' ? nil : heading.presence) where(heading_id: heading == 'all' ? nil : heading.presence)
end end
def budget
heading.group.budget
end
def undecided? def undecided?
feasibility == "undecided" feasibility == "undecided"
end end
@@ -140,7 +139,7 @@ class Budget
end end
def code def code
"B#{budget_id}I#{id}" "B#{budget.id}I#{id}"
end end
def reason_for_not_being_selectable_by(user) def reason_for_not_being_selectable_by(user)
@@ -152,7 +151,7 @@ class Budget
def reason_for_not_being_ballotable_by(user, ballot) def reason_for_not_being_ballotable_by(user, ballot)
return permission_problem(user) if permission_problem?(user) return permission_problem(user) if permission_problem?(user)
return :no_ballots_allowed unless budget.balloting? return :no_ballots_allowed unless budget.balloting?
return :different_heading_assigned unless heading_id.blank? || ballot.blank? || heading_id == ballot.heading_id || ballot.heading_id.nil? return :different_heading_assigned unless ballot.valid_heading?(heading)
return :not_enough_money if ballot.present? && !enough_money?(ballot) return :not_enough_money if ballot.present? && !enough_money?(ballot)
end end

View File

@@ -0,0 +1,22 @@
class DirectMessage < ActiveRecord::Base
belongs_to :sender, class_name: 'User', foreign_key: 'sender_id'
belongs_to :receiver, class_name: 'User', foreign_key: 'receiver_id'
validates :title, presence: true
validates :body, presence: true
validates :sender, presence: true
validates :receiver, presence: true
validate :max_per_day
scope :today, lambda { where('DATE(created_at) = ?', Date.today) }
def max_per_day
return if errors.any?
max = Setting[:direct_message_max_per_day]
if sender.direct_messages_sent.today.count >= max.to_i
errors.add(:title, I18n.t('activerecord.errors.models.direct_message.attributes.max_per_day.invalid'))
end
end
end

View File

@@ -21,4 +21,30 @@ class Notification < ActiveRecord::Base
Notification.create!(user_id: user_id, notifiable: notifiable) Notification.create!(user_id: user_id, notifiable: notifiable)
end end
end end
def notifiable_title
case notifiable.class.name
when "ProposalNotification"
notifiable.proposal.title
when "Comment"
notifiable.commentable.title
else
notifiable.title
end
end
def notifiable_action
case notifiable_type
when "ProposalNotification"
"proposal_notification"
when "Comment"
"replies_to"
else
"comments_on"
end
end
def linkable_resource
notifiable.is_a?(ProposalNotification) ? notifiable.proposal : notifiable
end
end end

View File

@@ -16,6 +16,7 @@ class Proposal < ActiveRecord::Base
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :geozone belongs_to :geozone
has_many :comments, as: :commentable has_many :comments, as: :commentable
has_many :proposal_notifications
validates :title, presence: true validates :title, presence: true
validates :question, presence: true validates :question, presence: true
@@ -93,6 +94,10 @@ class Proposal < ActiveRecord::Base
cached_votes_up + physical_votes cached_votes_up + physical_votes
end end
def voters
votes_for.voters
end
def editable? def editable?
total_votes <= Setting["max_votes_for_proposal_edit"].to_i total_votes <= Setting["max_votes_for_proposal_edit"].to_i
end end
@@ -146,6 +151,10 @@ class Proposal < ActiveRecord::Base
Setting['votes_for_proposal_success'].to_i Setting['votes_for_proposal_success'].to_i
end end
def notifications
proposal_notifications
end
protected protected
def set_responsible_name def set_responsible_name

View File

@@ -0,0 +1,17 @@
class ProposalNotification < ActiveRecord::Base
belongs_to :author, class_name: 'User', foreign_key: 'author_id'
belongs_to :proposal
validates :title, presence: true
validates :body, presence: true
validates :proposal, presence: true
validate :minimum_interval
def minimum_interval
return true if proposal.try(:notifications).blank?
if proposal.notifications.last.created_at > (Time.now - Setting[:proposal_notification_minimum_interval_in_days].to_i.days).to_datetime
errors.add(:title, I18n.t('activerecord.errors.models.proposal_notification.attributes.minimum_interval.invalid', interval: Setting[:proposal_notification_minimum_interval_in_days]))
end
end
end

View File

@@ -2,6 +2,20 @@ class Setting < ActiveRecord::Base
validates :key, presence: true, uniqueness: true validates :key, presence: true, uniqueness: true
default_scope { order(id: :asc) } default_scope { order(id: :asc) }
scope :banner_style, -> { where("key ilike ?", "banner-style.%")}
scope :banner_img, -> { where("key ilike ?", "banner-img.%")}
def type
if feature_flag?
'feature'
elsif banner_style?
'banner-style'
elsif banner_img?
'banner-img'
else
'common'
end
end
def feature_flag? def feature_flag?
key.start_with?('feature.') key.start_with?('feature.')
@@ -11,6 +25,14 @@ class Setting < ActiveRecord::Base
feature_flag? && value.present? feature_flag? && value.present?
end end
def banner_style?
key.start_with?('banner-style.')
end
def banner_img?
key.start_with?('banner-img.')
end
class << self class << self
def [](key) def [](key)
where(key: key).pluck(:value).first.presence where(key: key).pluck(:value).first.presence

View File

@@ -23,6 +23,8 @@ class User < ActiveRecord::Base
has_many :spending_proposals, foreign_key: :author_id has_many :spending_proposals, foreign_key: :author_id
has_many :failed_census_calls has_many :failed_census_calls
has_many :notifications has_many :notifications
has_many :direct_messages_sent, class_name: 'DirectMessage', foreign_key: :sender_id
has_many :direct_messages_received, class_name: 'DirectMessage', foreign_key: :receiver_id
belongs_to :geozone belongs_to :geozone
validates :username, presence: true, if: :username_required? validates :username, presence: true, if: :username_required?
@@ -50,6 +52,7 @@ class User < ActiveRecord::Base
scope :officials, -> { where("official_level > 0") } scope :officials, -> { where("official_level > 0") }
scope :for_render, -> { includes(:organization) } scope :for_render, -> { includes(:organization) }
scope :by_document, -> (document_type, document_number) { where(document_type: document_type, document_number: document_number) } scope :by_document, -> (document_type, document_number) { where(document_type: document_type, document_number: document_number) }
scope :email_digest, -> { where(email_digest: true) }
before_validation :clean_document_number before_validation :clean_document_number
@@ -135,6 +138,16 @@ class User < ActiveRecord::Base
update official_position: nil, official_level: 0 update official_position: nil, official_level: 0
end end
def has_official_email?
domain = Setting['email_domain_for_officials']
!email.blank? && ( (email.end_with? "@#{domain}") || (email.end_with? ".#{domain}") )
end
def display_official_position_badge?
return true if official_level > 1
official_position_badge? && official_level == 1
end
def block def block
debates_ids = Debate.where(author_id: id).pluck(:id) debates_ids = Debate.where(author_id: id).pluck(:id)
comments_ids = Comment.where(user_id: id).pluck(:id) comments_ids = Comment.where(user_id: id).pluck(:id)
@@ -199,11 +212,6 @@ class User < ActiveRecord::Base
!erased? !erased?
end end
def has_official_email?
domain = Setting['email_domain_for_officials']
!email.blank? && ( (email.end_with? "@#{domain}") || (email.end_with? ".#{domain}") )
end
def locale def locale
self[:locale] ||= I18n.default_locale.to_s self[:locale] ||= I18n.default_locale.to_s
end end

View File

@@ -34,7 +34,9 @@
<div> <div>
<%= f.label :public_activity do %> <%= f.label :public_activity do %>
<%= f.check_box :public_activity, title: t('account.show.public_activity_label'), label: false %> <%= f.check_box :public_activity, title: t('account.show.public_activity_label'), label: false %>
<span class="checkbox"><%= t("account.show.public_activity_label") %></span> <span class="checkbox">
<%= t("account.show.public_activity_label") %>
</span>
<% end %> <% end %>
</div> </div>
@@ -43,24 +45,61 @@
<div> <div>
<%= f.label :email_on_comment do %> <%= f.label :email_on_comment do %>
<%= f.check_box :email_on_comment, title: t('account.show.email_on_comment_label'), label: false %> <%= f.check_box :email_on_comment, title: t('account.show.email_on_comment_label'), label: false %>
<span class="checkbox"><%= t("account.show.email_on_comment_label") %></span> <span class="checkbox">
<%= t("account.show.email_on_comment_label") %>
</span>
<% end %> <% end %>
</div> </div>
<div> <div>
<%= f.label :email_on_comment_reply do %> <%= f.label :email_on_comment_reply do %>
<%= f.check_box :email_on_comment_reply, title: t('account.show.email_on_comment_reply_label'), label: false %> <%= f.check_box :email_on_comment_reply, title: t('account.show.email_on_comment_reply_label'), label: false %>
<span class="checkbox"><%= t("account.show.email_on_comment_reply_label") %></span> <span class="checkbox">
<%= t("account.show.email_on_comment_reply_label") %>
</span>
<% end %> <% end %>
</div> </div>
<div> <div>
<%= f.label :email_newsletter_subscribed do %> <%= f.label :email_newsletter_subscribed do %>
<%= f.check_box :newsletter, title: t('account.show.subscription_to_website_newsletter_label'), label: false %> <%= f.check_box :newsletter, title: t('account.show.subscription_to_website_newsletter_label'), label: false %>
<span class="checkbox"><%= t("account.show.subscription_to_website_newsletter_label") %></span> <span class="checkbox">
<%= t("account.show.subscription_to_website_newsletter_label") %>
</span>
<% end %> <% end %>
</div> </div>
<div>
<%= f.label :email_digest do %>
<%= f.check_box :email_digest, title: t('account.show.email_digest_label'), label: false %>
<span class="checkbox">
<%= t("account.show.email_digest_label") %>
</span>
<% end %>
</div>
<div>
<%= f.label :email_on_direct_message do %>
<%= f.check_box :email_on_direct_message, title: t('account.show.email_on_direct_message_label'), label: false %>
<span class="checkbox">
<%= t("account.show.email_on_direct_message_label") %>
</span>
<% end %>
</div>
<% if @account.official_level == 1 %>
<div>
<%= f.label :official_position_badge do %>
<%= f.check_box :official_position_badge,
title: t('account.show.official_position_badge_label'),
label: false %>
<span class="checkbox">
<%= t("account.show.official_position_badge_label") %>
</span>
<% end %>
</div>
<% end %>
<%= f.submit t("account.show.save_changes_submit"), class: "button" %> <%= f.submit t("account.show.save_changes_submit"), class: "button" %>
</div> </div>

View File

@@ -1,115 +1,103 @@
<nav class="admin-sidebar"> <nav class="admin-sidebar">
<ul id="admin_menu"> <ul id="admin_menu">
<li>
<%= link_to t("admin.dashboard.index.title"), admin_root_path %>
</li>
<li <%= "class=active" if controller_name == "tags" %>> <li <%= "class=active" if controller_name == "tags" %>>
<%= link_to admin_tags_path do %> <%= link_to admin_tags_path do %>
<span class="icon-tag"></span> <span class="icon-tag"></span><%= t("admin.menu.debate_topics") %>
<%= t("admin.menu.debate_topics") %>
<% end %> <% end %>
</li> </li>
<li <%= "class=active" if controller_name == "proposals" %>> <li <%= "class=active" if controller_name == "proposals" %>>
<%= link_to admin_proposals_path do %> <%= link_to admin_proposals_path do %>
<span class="icon-proposals"></span> <span class="icon-proposals"></span><%= t("admin.menu.hidden_proposals") %>
<%= t("admin.menu.hidden_proposals") %>
<% end %> <% end %>
</li> </li>
<% if feature?(:debates) %> <% if feature?(:debates) %>
<li <%= "class=active" if controller_name == "debates" %>> <li <%= "class=active" if controller_name == "debates" %>>
<%= link_to admin_debates_path do %> <%= link_to admin_debates_path do %>
<span class="icon-debates"></span> <span class="icon-debates"></span><%= t("admin.menu.hidden_debates") %>
<%= t("admin.menu.hidden_debates") %>
<% end %> <% end %>
</li> </li>
<% end %> <% end %>
<li <%= "class=active" if controller_name == "comments" %>> <li <%= "class=active" if controller_name == "comments" %>>
<%= link_to admin_comments_path do %> <%= link_to admin_comments_path do %>
<span class="icon-comments"></span> <span class="icon-comments"></span><%= t("admin.menu.hidden_comments") %>
<%= t("admin.menu.hidden_comments") %>
<% end %> <% end %>
</li> </li>
<% if feature?(:spending_proposals) %> <% if feature?(:spending_proposals) %>
<li <%= "class=active" if controller_name == "spending_proposals" %>> <li <%= "class=active" if controller_name == "spending_proposals" %>>
<%= link_to admin_spending_proposals_path do %> <%= link_to admin_spending_proposals_path do %>
<span class="icon-budget"></span> <span class="icon-budget"></span><%= t("admin.menu.spending_proposals") %>
<%= t("admin.menu.spending_proposals") %>
<% end %> <% end %>
</li> </li>
<% end %> <% end %>
<li <%= "class=active" if controller_name == "banners" %>>
<%= link_to admin_banners_path do %>
<span class="icon-eye"></span><%= t("admin.menu.banner") %>
<% end %>
</li>
<li <%= "class=active" if controller_name == "users" %>> <li <%= "class=active" if controller_name == "users" %>>
<%= link_to admin_users_path do %> <%= link_to admin_users_path do %>
<span class="icon-eye"></span> <span class="icon-eye"></span><%= t("admin.menu.hidden_users") %>
<%= t("admin.menu.hidden_users") %>
<% end %> <% end %>
</li> </li>
<li <%= "class=active" if controller_name == "verifications" %>> <li <%= "class=active" if controller_name == "verifications" %>>
<%= link_to admin_verifications_path do %> <%= link_to admin_verifications_path do %>
<span class="icon-eye"></span> <span class="icon-eye"></span><%= t("admin.menu.incomplete_verifications") %>
<%= t("admin.menu.incomplete_verifications") %>
<% end %> <% end %>
</li> </li>
<li <%= "class=active" if controller_name == "organizations" %>> <li <%= "class=active" if controller_name == "organizations" %>>
<%= link_to admin_organizations_path do %> <%= link_to admin_organizations_path do %>
<span class="icon-organizations"></span> <span class="icon-organizations"></span><%= t("admin.menu.organizations") %>
<%= t("admin.menu.organizations") %>
<% end %> <% end %>
</li> </li>
<li <%= "class=active" if controller_name == "officials" %>> <li <%= "class=active" if controller_name == "officials" %>>
<%= link_to admin_officials_path do %> <%= link_to admin_officials_path do %>
<span class="icon-user"></span> <span class="icon-user"></span><%= t("admin.menu.officials") %>
<%= t("admin.menu.officials") %>
<% end %> <% end %>
</li> </li>
<li <%= 'class=active' if controller_name == 'moderators' %>> <li <%= 'class=active' if controller_name == 'moderators' %>>
<%= link_to admin_moderators_path do %> <%= link_to admin_moderators_path do %>
<span class="icon-user"></span> <span class="icon-user"></span><%= t('admin.menu.moderators') %>
<%= t('admin.menu.moderators') %>
<% end %> <% end %>
</li> </li>
<li <%= 'class=active' if controller_name == 'valuators' %>> <li <%= 'class=active' if controller_name == 'valuators' %>>
<%= link_to admin_valuators_path do %> <%= link_to admin_valuators_path do %>
<span class="icon-user"></span> <span class="icon-user"></span><%= t('admin.menu.valuators') %>
<%= t('admin.menu.valuators') %>
<% end %> <% end %>
</li> </li>
<li <%= 'class=active' if controller_name == 'managers' %>> <li <%= 'class=active' if controller_name == 'managers' %>>
<%= link_to admin_managers_path do %> <%= link_to admin_managers_path do %>
<span class="icon-user"></span> <span class="icon-user"></span><%= t('admin.menu.managers') %>
<%= t('admin.menu.managers') %>
<% end %> <% end %>
</li> </li>
<li <%= 'class=active' if controller_name == 'activity' %>> <li <%= 'class=active' if controller_name == 'activity' %>>
<%= link_to admin_activity_path do %> <%= link_to admin_activity_path do %>
<span class="icon-eye"></span> <span class="icon-eye"></span><%= t('admin.menu.activity') %>
<%= t('admin.menu.activity') %>
<% end %> <% end %>
</li> </li>
<li <%= 'class=active' if controller_name == 'settings' %>> <li <%= 'class=active' if controller_name == 'settings' %>>
<%= link_to admin_settings_path do %> <%= link_to admin_settings_path do %>
<span class="icon-settings"></span> <span class="icon-settings"></span><%= t("admin.menu.settings") %>
<%= t("admin.menu.settings") %>
<% end %> <% end %>
</li> </li>
<li <%= "class=active" if controller_name == "stats" %>> <li <%= "class=active" if controller_name == "stats" %>>
<%= link_to admin_stats_path do %> <%= link_to admin_stats_path do %>
<span class="icon-stats"></span> <span class="icon-stats"></span><%= t("admin.menu.stats") %>
<%= t("admin.menu.stats") %>
<% end %> <% end %>
</li> </li>
</ul> </ul>

View File

@@ -8,7 +8,7 @@
<tr> <tr>
<th><%= t("admin.activity.show.type") %></th> <th><%= t("admin.activity.show.type") %></th>
<th><%= t("admin.activity.show.action") %></th> <th><%= t("admin.activity.show.action") %></th>
<th> </th> <th class="text-left"><%= t("admin.activity.show.content") %></th>
<th><%= t("admin.activity.show.by") %></th> <th><%= t("admin.activity.show.by") %></th>
</tr> </tr>
<% @activity.each do |activity| %> <% @activity.each do |activity| %>

View File

@@ -0,0 +1,15 @@
<% if @banner.errors.any? %>
<div id="error_explanation" data-alert class="callout alert" data-closable>
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
<span aria-hidden="true">&times;</span>
</button>
<strong>
<%= @banner.errors.count %>
<%= t("admin.banners.errors.form.error", count: @banner.errors.count) %>
</strong>
</div>
<% end %>

View File

@@ -0,0 +1,76 @@
<%= form_for [:admin, @banner] do |f| %>
<%= render 'errors' %>
<div class="row">
<div class="small-12 medium-6 large-3 column">
<%= f.label :style, t("admin.banners.banner.style") %>
<%= f.select :style, options_for_select(@banner_styles, @banner.style),:include_blank => '-',
label: false,placeholder: t("admin.banners.banner.style") %>
</div>
<div class="small-12 medium-6 large-3 column">
<%= f.label :image, t("admin.banners.banner.image") %>
<%= f.select :image, options_for_select(@banner_imgs, @banner.image),:include_blank => '-',
label: false, placeholder: t("admin.banners.banner.image") %>
</div>
<% date_started_at = @banner.post_started_at.present? ? I18n.localize(@banner.post_started_at) : "" %>
<div class="small-12 medium-6 large-3 column">
<%= f.label :post_started_at, t("admin.banners.banner.post_started_at") %>
<%= f.text_field :post_started_at,
label: false,
placeholder: t("admin.banners.banner.post_started_at"),
value: date_started_at,
class: "js-calendar-full",
id: "post_started_at" %>
</div>
<% date_ended_at = @banner.post_ended_at.present? ? I18n.localize(@banner.post_ended_at) : ""%>
<div class="small-12 medium-6 large-3 column">
<%= f.label :post_ended_at, t("admin.banners.banner.post_ended_at") %>
<%= f.text_field :post_ended_at,
label: false,
placeholder: t("admin.banners.banner.post_ended_at"),
value: date_ended_at,
class: "js-calendar-full",
id: "post_ended_at" %>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 column">
<%= f.label :title, t("admin.banners.banner.title") %>
<%= f.text_field :title, placeholder: t("admin.banners.banner.title"), label: false,
data: {js_banner_title: "js_banner_title"} %>
</div>
<div class="small-12 medium-6 column">
<%= f.label :target_url, t("admin.banners.banner.target_url") %>
<%= f.text_field :target_url,
label: false,
placeholder: t("admin.banners.banner.target_url") %>
</div>
</div>
<div class="row">
<div class="small-12 column">
<%= f.label :description, t("admin.banners.banner.description") %>
<%= f.text_field :description,
label: false,
data: {js_banner_description: "js_banner_description"},
placeholder: t("admin.banners.banner.description") %>
</div>
</div>
<div class="row">
<div class="actions small-12 medium-3 column">
<%= f.submit(class: "button expanded", value: t("admin.banners.edit.form.submit_button")) %>
</div>
</div>
<div id="js-banner-style" class="<%= @banner.style %>">
<div id="js-banner-image" class="<%= @banner.image %>">
<%= link_to @banner.target_url do %>
<h2 id="js-banner-title"><%= @banner.title %></h2>
<h3 id="js-banner-description"><%= @banner.description %></h3>
<% end %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,13 @@
<div class="banner-edit row">
<div class="small-12 column">
<%= link_to admin_banners_path, class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.banners.edit.back") %>
<% end %>
<h1><%= t("admin.banners.edit.editing") %></h1>
<%= render "form" %>
</div>
</div>

View File

@@ -0,0 +1,42 @@
<%= link_to t("admin.banners.index.create"),
new_admin_banner_path, class: "button success float-right" %>
<h2 class="inline-block"><%= t("admin.banners.index.title") %></h2>
<%= render 'shared/filter_subnav', i18n_namespace: "admin.banners.index" %>
<h3><%= page_entries_info @banners %></h3>
<table>
<% @banners.each do |banner| %>
<tr id="<%= dom_id(banner) %>">
<td class="small-12 medium-9">
<small>
<%= t("admin.banners.banner.post_started_at")%> <strong><%= banner.post_started_at %></strong>
&nbsp;|&nbsp;
<%= t("admin.banners.banner.post_ended_at")%> <strong><%= banner.post_ended_at%></strong>
</small>
<div class="<%= banner.style %>">
<div class="<%= banner.image %>">
<%= link_to banner.target_url do %>
<h2><%= banner.title %></h2>
<h3><%= banner.description %></h3>
<% end %>
</div>
</div>
</td>
<td class="text-right">
<%= link_to t("admin.banners.index.edit"), edit_admin_banner_path(banner),
class: 'edit-banner button hollow' %>
<%= link_to t("admin.banners.index.delete"), admin_banner_path(banner),
method: :delete,
class: 'button hollow alert' %>
</td>
</tr>
<% end %>
</table>
<%= paginate @banners %>

View File

@@ -0,0 +1,13 @@
<div class="banner-new row">
<div class="small-12 column">
<%= link_to admin_banners_path, class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.banners.new.back") %>
<% end %>
<h1><%= t("admin.banners.new.creating") %></h1>
<%= render "form" %>
</div>
</div>

View File

@@ -4,34 +4,32 @@
<h3><%= page_entries_info @comments %></h3> <h3><%= page_entries_info @comments %></h3>
<ul class="admin-list"> <table>
<% @comments.each do |comment| %> <% @comments.each do |comment| %>
<li id="<%= dom_id(comment) %>"> <tr id="<%= dom_id(comment) %>">
<div class="row"> <td>
<div class="small-12 medium-8 column">
<%= text_with_links comment.body %><br> <%= text_with_links comment.body %><br>
<% if comment.commentable.hidden? %> <% if comment.commentable.hidden? %>
(<%= t("admin.comments.index.hidden_#{comment.commentable_type.downcase}") %>: <%= comment.commentable.title %>) (<%= t("admin.comments.index.hidden_#{comment.commentable_type.downcase}") %>: <%= comment.commentable.title %>)
<% else %> <% else %>
<%= link_to comment.commentable.title, comment.commentable %> <%= link_to comment.commentable.title, comment.commentable %>
<% end %> <% end %>
</div> </td>
<div class="small-6 medium-4 column text-right"> <td class="text-right">
<%= link_to t("admin.actions.restore"), <%= link_to t("admin.actions.restore"),
restore_admin_comment_path(comment, request.query_parameters), restore_admin_comment_path(comment, request.query_parameters),
method: :put, method: :put,
data: { confirm: t("admin.actions.confirm") }, data: { confirm: t("admin.actions.confirm") },
class: "button small success float-right" %> class: "button hollow on-hover-block" %>
<% unless comment.confirmed_hide? %> <% unless comment.confirmed_hide? %>
<%= link_to t("admin.actions.confirm_hide"), <%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_comment_path(comment, request.query_parameters), confirm_hide_admin_comment_path(comment, request.query_parameters),
method: :put, method: :put,
class: "button small warning float-right" %> class: "button hollow warning on-hover-block" %>
<% end %> <% end %>
</div> </td>
</div> </tr>
</li>
<% end %> <% end %>
</ul> </table>
<%= paginate @comments %> <%= paginate @comments %>

View File

@@ -1,12 +1,22 @@
<div class="dashboard"> <%= link_to t("admin.dashboard.index.back") + " " + setting['org_name'], root_path, class: "button float-right" %>
<h2><%= t("admin.dashboard.index.title") %></h2>
<h2 class="inline-block"><%= t("admin.dashboard.index.title") %></h2>
<p>Desde aquí puedes administrar el sistema, a través de las siguientes acciones:</p> <p>Desde aquí puedes administrar el sistema, a través de las siguientes acciones:</p>
<h3>Temas de debate</h3> <div class="small-12 medium-9">
<p>Los temas (también llamadas tags, o etiquetas) de debate son palabras que definen los usuarios al crear debates, para catalogarlos (ej: sanidad, movilidad, arganzuela, ...). Aquí se pueden eliminar temas inapropiados, o <strong>marcarlos para ser propuestos al crear debates</strong> (cada usuario puede definir los que quiera, pero se le sugieren algunos que nos parecen útiles como catalogación por defecto; aquí se puede cambiar cuáles se sugieren)</p> <ul class="accordion" data-accordion data-multi-expand="true" data-allow-all-closed="true">
<h3>Propuestas/Debates/Comentarios ocultos</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Temas de debate</a>
<div class="accordion-content" data-tab-content>
<p>Los temas (también llamadas tags, o etiquetas) de debate son palabras que definen los usuarios al crear debates, para catalogarlos (ej: sanidad, movilidad, arganzuela, ...). Aquí se pueden eliminar temas inapropiados, o <strong>marcarlos para ser propuestos al crear debates</strong> (cada usuario puede definir los que quiera, pero se le sugieren algunos que nos parecen útiles como catalogación por defecto; aquí se puede cambiar cuáles se sugieren)</p>
</div>
</li>
<li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Propuestas/Debates/Comentarios ocultos</a>
<div class="accordion-content" data-tab-content>
<p>Cuando un moderador o un administrador oculta una Propuesta/Debate/Comentario aparecerá en esta lista. De esta forma los administradores pueden revisar que se ha ocultado el elemento adecuado.</p> <p>Cuando un moderador o un administrador oculta una Propuesta/Debate/Comentario aparecerá en esta lista. De esta forma los administradores pueden revisar que se ha ocultado el elemento adecuado.</p>
<ul> <ul>
@@ -18,34 +28,64 @@
<p>Para facilitar la gestión, arriba encontramos un <strong>filtro</strong> con las secciones: "pendientes" (los elementos sobre los que todavía no se ha pulsado "confirmar" o "volver a mostrar", que deberían ser revisados todavía), "confirmados" y "todos".</p> <p>Para facilitar la gestión, arriba encontramos un <strong>filtro</strong> con las secciones: "pendientes" (los elementos sobre los que todavía no se ha pulsado "confirmar" o "volver a mostrar", que deberían ser revisados todavía), "confirmados" y "todos".</p>
<p><em>Es recomendable revisar regularmente la sección "pendientes".</em></p> <p><em>Es recomendable revisar regularmente la sección "pendientes".</em></p>
</div>
</li>
<h3>Usuarios bloqueados</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Usuarios bloqueados</a>
<div class="accordion-content" data-tab-content>
<p>Cuando un moderador o un administrador bloquea a un usuario aparecerá en esta lista. Al <strong>bloquear a un usuario, éste deja de poder utilizarlo para ninguna acción de la web</strong>. Los administradores pueden desbloquearlos pulsando el botón al lado del nombre del usuario en la lista.</p> <p>Cuando un moderador o un administrador bloquea a un usuario aparecerá en esta lista. Al <strong>bloquear a un usuario, éste deja de poder utilizarlo para ninguna acción de la web</strong>. Los administradores pueden desbloquearlos pulsando el botón al lado del nombre del usuario en la lista.</p>
</div>
</li>
<h3>Organizaciones</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Organizaciones</a>
<div class="accordion-content" data-tab-content>
<p>En la web hay dos tipos de usuarios: individuales y organizaciones. Cualquier persona puede crear usuarios de un tipo o de otro en la propia web. Los usuarios de organizaciones pueden ser verificados por parte de los administradores, confirmando que quien gestiona el usuario efectivamente representa a esa organización. Una vez se haya realizado el proceso de verificación, por el proceso externo a la web que se haya definido para ello, se pulsa el botón <strong>"Verificar"</strong> para confimarlo; lo que hará que al lado del nombre de la organización aparezca una etiqueta señalando que es una organización verificada.</p> <p>En la web hay dos tipos de usuarios: individuales y organizaciones. Cualquier persona puede crear usuarios de un tipo o de otro en la propia web. Los usuarios de organizaciones pueden ser verificados por parte de los administradores, confirmando que quien gestiona el usuario efectivamente representa a esa organización. Una vez se haya realizado el proceso de verificación, por el proceso externo a la web que se haya definido para ello, se pulsa el botón <strong>"Verificar"</strong> para confimarlo; lo que hará que al lado del nombre de la organización aparezca una etiqueta señalando que es una organización verificada.</p>
<p>En caso de que el proceso de verificación haya sido negativo, se pulsa el botón <strong>"Rechazar"</strong>. Para editar alguno de los datos de la organización, se pulsa el botón <strong>"Editar"</strong>.</p> <p>En caso de que el proceso de verificación haya sido negativo, se pulsa el botón <strong>"Rechazar"</strong>. Para editar alguno de los datos de la organización, se pulsa el botón <strong>"Editar"</strong>.</p>
<p>En caso de que el proceso de verificación haya sido negativo, se pulsa el botón <strong>"Rechazar"</strong>. Para editar alguno de los datos de la organización, se pulsa el botón <strong>"Editar"</strong>.</p>
<p>Las organizaciones que no aparecen en la lista pueden ser encontradas para actuar sobre ellas por medio del buscador en la parte superior. Para facilitar la gestión, arriba <p>Las organizaciones que no aparecen en la lista pueden ser encontradas para actuar sobre ellas por medio del buscador en la parte superior. Para facilitar la gestión, arriba
encontramos un <strong>filtro</strong> con las secciones: "pendientes" (las organizaciones que todavía no han sido verificadas o rechazadas), "verificadas", "rechazadas" y "todas".</p> encontramos un <strong>filtro</strong> con las secciones: "pendientes" (las organizaciones que todavía no han sido verificadas o rechazadas), "verificadas", "rechazadas" y "todas".</p>
<p><em>Es recomendable revisar regularmente la sección "pendientes".</em></p> <p><em>Es recomendable revisar regularmente la sección "pendientes".</em></p>
</div>
</li>
<h3>Cargos Públicos</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Cargos Públicos</a>
<div class="accordion-content" data-tab-content>
<p>En la web, los usuarios individuales pueden ser usuarios normales, o cargos públicos. Estos últimos se diferencian de los primeros únicamente en que al lado de sus nombres aparece una <strong>etiqueta que les identifica</strong>, y cambia ligeramente el estilo de sus comentarios. Esto permite que los usuarios les identifiquen más fácilmente. Al lado de cada usuario vemos la identificación que aparece en su etiqueta, y <strong>su nivel</strong> (la manera que internamente usa la web para diferenciar entre un tipo de cargos y otros). Pulsando el botón <strong>"Editar"</strong> al lado del usuario, se puede modificar su información. Los cargos públicos que no aparecen en la lista pueden ser encontrados para actuar sobre ellos por medio del buscador en la parte superior.</p> <p>En la web, los usuarios individuales pueden ser usuarios normales, o cargos públicos. Estos últimos se diferencian de los primeros únicamente en que al lado de sus nombres aparece una <strong>etiqueta que les identifica</strong>, y cambia ligeramente el estilo de sus comentarios. Esto permite que los usuarios les identifiquen más fácilmente. Al lado de cada usuario vemos la identificación que aparece en su etiqueta, y <strong>su nivel</strong> (la manera que internamente usa la web para diferenciar entre un tipo de cargos y otros). Pulsando el botón <strong>"Editar"</strong> al lado del usuario, se puede modificar su información. Los cargos públicos que no aparecen en la lista pueden ser encontrados para actuar sobre ellos por medio del buscador en la parte superior.</p>
</div>
</li>
<h3>Moderadores</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Moderadores</a>
<p>Mediante el buscador de la parte superior se pueden buscar usuarios, para activarlos o desactivarlos como moderadores de la web. Los moderadores al acceder a la web con su usuario ven en la parte <div class="accordion-content" data-tab-content>
superior una nueva sección llamada <strong>"Moderar"</strong></p> <p>Mediante el buscador de la parte superior se pueden buscar usuarios, para activarlos o desactivarlos como moderadores de la web. Los moderadores al acceder a la web con su usuario ven en la parte superior una nueva sección llamada <strong>"Moderar"</strong></p>
</div>
<h3>Actividad de moderadores</h3> </li>
<li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Actividad de moderadores</a>
<div class="accordion-content" data-tab-content>
<p>En esta sección se va guardando <strong>todas las acciones que realizan los moderadores o los administradores respecto a la moderación</strong>: ocultar/mostrar Propuestas/Debates/Comentarios y bloquear usuarios. En la columna <strong>"Acción"</strong> comprobamos si la acción corresponde con ocultar o con volver a mostrar (restaurar) elementos o con bloquear usuarios. En las demás columnas tenemos el tipo de elemento, el contenido del elemento y el moderador o administrador que ha realizado la acción. Esta sección permite que los administradores detecten comportamientos irregulares por parte de moderadores específicos y que por lo tanto puedan corregirlos.</p> <p>En esta sección se va guardando <strong>todas las acciones que realizan los moderadores o los administradores respecto a la moderación</strong>: ocultar/mostrar Propuestas/Debates/Comentarios y bloquear usuarios. En la columna <strong>"Acción"</strong> comprobamos si la acción corresponde con ocultar o con volver a mostrar (restaurar) elementos o con bloquear usuarios. En las demás columnas tenemos el tipo de elemento, el contenido del elemento y el moderador o administrador que ha realizado la acción. Esta sección permite que los administradores detecten comportamientos irregulares por parte de moderadores específicos y que por lo tanto puedan corregirlos.</p>
</div>
</li>
<h3>Configuración Global</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Configuración Global</a>
<div class="accordion-content" data-tab-content>
<p>Opciones generales de configuración del sistema.</p> <p>Opciones generales de configuración del sistema.</p>
</div>
</li>
<h3>Estadísticas</h3> <li class="accordion-item" data-accordion-item>
<a href="#" class="accordion-title">Estadísticas</a>
<div class="accordion-content" data-tab-content>
<p>Estadísticas generales del sistema.</p> <p>Estadísticas generales del sistema.</p>
</div> </div>
</li>
</ul>
</div>

View File

@@ -14,19 +14,17 @@
<%= debate.description %> <%= debate.description %>
</div> </div>
</td> </td>
<td> <td class="text-right">
<%= link_to t("admin.actions.restore"), <%= link_to t("admin.actions.restore"),
restore_admin_debate_path(debate, request.query_parameters), restore_admin_debate_path(debate, request.query_parameters),
method: :put, method: :put,
data: { confirm: t("admin.actions.confirm") }, data: { confirm: t("admin.actions.confirm") },
class: "button small success no-margin" %> class: "button hollow on-hover" %>
</td>
<td>
<% unless debate.confirmed_hide? %> <% unless debate.confirmed_hide? %>
<%= link_to t("admin.actions.confirm_hide"), <%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_debate_path(debate, request.query_parameters), confirm_hide_admin_debate_path(debate, request.query_parameters),
method: :put, method: :put,
class: "button small warning float-right" %> class: "button hollow warning on-hover" %>
<% end %> <% end %>
</td> </td>
</tr> </tr>

View File

@@ -1,13 +1,24 @@
<span><%= manager.name %></span> <div class="small-12 column">
<span class="bullet">&nbsp;&bull;&nbsp;</span> <table>
<span><%= manager.email %></span> <tr>
<td>
<%= manager.name %>
</td>
<td>
<%= manager.email %>
</td>
<td class="text-right">
<% if manager.persisted? %> <% if manager.persisted? %>
<%= link_to t('admin.managers.manager.delete'), <%= link_to t('admin.managers.manager.delete'),
admin_manager_path(manager), admin_manager_path(manager),
method: :delete, method: :delete,
class: "button small alert float-right" class: "button hollow alert"
%> %>
<% else %> <% else %>
<%= link_to t('admin.managers.manager.add'),{ controller: "admin/managers", action: :create, user_id: manager.user_id }, <%= link_to t('admin.managers.manager.add'),{ controller: "admin/managers", action: :create, user_id: manager.user_id },
method: :post, class: "button small success float-right" %> method: :post, class: "button success" %>
<% end %> <% end %>
</td>
</tr>
</table>
</div>

View File

@@ -1,6 +1,6 @@
<h2><%= t("admin.managers.index.title") %></h2> <h2><%= t("admin.managers.index.title") %></h2>
<div class="row"> <div class="row">
<div class="column">
<%= form_tag search_admin_managers_path, method: :get, remote: true do %> <%= form_tag search_admin_managers_path, method: :get, remote: true do %>
<div class="small-12 medium-6 column"> <div class="small-12 medium-6 column">
<%= text_field_tag :email, '', placeholder: t('admin.managers.search.email_placeholder') %> <%= text_field_tag :email, '', placeholder: t('admin.managers.search.email_placeholder') %>
@@ -10,15 +10,34 @@
</div> </div>
<% end %> <% end %>
</div> </div>
</div>
<div id="search-result" class="row small"></div> <div id="search-result" class="row"></div>
<h3><%= page_entries_info @managers %></h3> <h3><%= page_entries_info @managers %></h3>
<ul id="managers" class="admin-list">
<table id="managers">
<% @managers.each do |manager| %> <% @managers.each do |manager| %>
<li> <tr>
<%= render 'manager', manager: manager %> <td>
</li> <%= manager.name %>
</td>
<td>
<%= manager.email %>
</td>
<td class="text-right">
<% if manager.persisted? %>
<%= link_to t('admin.managers.manager.delete'),
admin_manager_path(manager),
method: :delete,
class: "button hollow alert"
%>
<% else %>
<%= link_to t('admin.managers.manager.add'),{ controller: "admin/managers", action: :create, user_id: manager.user_id },
method: :post, class: "button success" %>
<% end %> <% end %>
</ul> </td>
</tr>
<% end %>
</table>
<%= paginate @managers %> <%= paginate @managers %>

View File

@@ -1 +1 @@
$("#search-result").html("<div class=\"panel column\"><%= j render 'manager', manager: @manager %></div>"); $("#search-result").html("<%= j render 'manager', manager: @manager %>");

View File

@@ -1 +1 @@
$("#search-result").html("<div class=\"panel column\"><%= j t('admin.managers.search.user_not_found') %></div>"); $("#search-result").html("<div class=\"small-12 column\"><div class=\"callout alert\"><%= j t('admin.managers.search.user_not_found') %></div></div>");

View File

@@ -1,13 +1,26 @@
<span><%= moderator.name %></span> <div class="small-12 column">
<span class="bullet">&nbsp;&bull;&nbsp;</span> <table>
<span><%= moderator.email %></span> <tbody>
<tr>
<td>
<%= moderator.name %>
</td>
<td>
<%= moderator.email %>
</td>
<td class="text-right">
<% if moderator.persisted? %> <% if moderator.persisted? %>
<%= link_to t('admin.moderators.moderator.delete'), <%= link_to t('admin.moderators.moderator.delete'),
admin_moderator_path(moderator), admin_moderator_path(moderator),
method: :delete, method: :delete,
class: "button small alert float-right" class: "button hollow alert" %>
%>
<% else %> <% else %>
<%= link_to t('admin.moderators.moderator.add'),{ controller: "admin/moderators", action: :create, user_id: moderator.user_id }, <%= link_to t('admin.moderators.moderator.add'),{ controller: "admin/moderators", action: :create, user_id: moderator.user_id },
method: :post, class: "button small success float-right" %> method: :post,
class: "button success" %>
<% end %> <% end %>
</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -1,6 +1,6 @@
<h2><%= t("admin.moderators.index.title") %></h2> <h2><%= t("admin.moderators.index.title") %></h2>
<div class="row"> <div class="row">
<div class="column">
<%= form_tag search_admin_moderators_path, method: :get, remote: true do %> <%= form_tag search_admin_moderators_path, method: :get, remote: true do %>
<div class="small-12 medium-6 column"> <div class="small-12 medium-6 column">
<%= text_field_tag :email, '', placeholder: t('admin.moderators.search.email_placeholder') %> <%= text_field_tag :email, '', placeholder: t('admin.moderators.search.email_placeholder') %>
@@ -10,15 +10,37 @@
</div> </div>
<% end %> <% end %>
</div> </div>
</div>
<div id="search-result" class="row small"></div> <div id="search-result" class="row"></div>
<h3><%= page_entries_info @moderators %></h3> <h3><%= page_entries_info @moderators %></h3>
<ul id="moderators" class="admin-list">
<table id="moderators">
<% @moderators.each do |moderator| %> <% @moderators.each do |moderator| %>
<li> <tr>
<%= render 'moderator', moderator: moderator %> <td>
</li> <%= moderator.name %>
</td>
<td>
<%= moderator.email %>
</td>
<td class="text-right">
<% if moderator.persisted? %>
<%= link_to t('admin.moderators.moderator.delete'),
admin_moderator_path(moderator),
method: :delete,
class: "button hollow alert"
%>
<% else %>
<%= link_to t('admin.moderators.moderator.add'),
{ controller: "admin/moderators", action: :create,
user_id: moderator.user_id },
method: :post,
class: "button success" %>
<% end %> <% end %>
</ul> </td>
</tr>
<% end %>
</table>
<%= paginate @moderators %> <%= paginate @moderators %>

View File

@@ -1 +1 @@
$("#search-result").html("<div class=\"panel column\"><%= j render 'moderator', moderator: @moderator %></div>"); $("#search-result").html("<%= j render 'moderator', moderator: @moderator %>");

View File

@@ -1 +1 @@
$("#search-result").html("<div class=\"panel column\"><%= j t('admin.moderators.search.user_not_found') %></div>"); $("#search-result").html("<div class=\"small-12 column\"><div class=\"callout alert\"><%= j t('admin.moderators.search.user_not_found') %></div></div>");

View File

@@ -1,15 +1,20 @@
<h2> <%= render 'shared/back_link' %>
<%= t("admin.officials.edit.title") %>
<span class="official float-right"><strong><%= @user.name %></strong> (<%= @user.email %>)</span>
</h2>
<div class="clear"></div>
<div class="official float-right"><strong><%= @user.name %></strong> (<%= @user.email %>)</div>
<h2 class="inline-block"><%= t("admin.officials.edit.title") %></h2>
<div class="row">
<div class="small-12 medium-6 column end">
<%= form_for @user, url: admin_official_path(@user) do |f| %> <%= form_for @user, url: admin_official_path(@user) do |f| %>
<%= f.text_field :official_position %> <%= f.text_field :official_position %>
<%= f.select :official_level, official_level_options %> <%= f.select :official_level, official_level_options %>
<%= link_to t("admin.officials.edit.back"), admin_officials_path, class: "button small secondary" %>
<%= f.submit %>
<% if @user.official? %> <% if @user.official? %>
<%= link_to t("admin.officials.edit.destroy"), admin_official_path(@user), method: :delete, class: 'delete' %> <%= link_to t("admin.officials.edit.destroy"), admin_official_path(@user), method: :delete, class: 'button hollow alert' %>
<% end %> <% end %>
<%= f.submit class: "button hollow" %>
<% end %> <% end %>
</div>
</div>

View File

@@ -4,20 +4,24 @@
<h3><%= page_entries_info @officials %></h3> <h3><%= page_entries_info @officials %></h3>
<ul class="admin-list"> <table>
<% @officials.each do |official| %> <% @officials.each do |official| %>
<li> <tr>
<td>
<%= link_to official.name, edit_admin_official_path(official) %> <%= link_to official.name, edit_admin_official_path(official) %>
<span class="bullet">&nbsp;&bull;&nbsp;</span> </td>
<span class="level"><%= t("admin.officials.level_#{official.official_level}") %></span> <td>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span class="label round level-<%= official.official_level %>"> <span class="label round level-<%= official.official_level %>">
<%= official.official_position %> <%= official.official_position %>
</span> </span>
(<%= t("admin.officials.level_#{official.official_level}") %>)
<%= link_to official.official? ? t("admin.officials.search.edit_official") : t("admin.officials.search.make_official"), edit_admin_official_path(official), class: "button small float-right" %> </td>
</li> <td class="text-right">
<%= link_to official.official? ? t("admin.officials.search.edit_official") : t("admin.officials.search.make_official"),
edit_admin_official_path(official), class: "button hollow" %>
</td>
</tr>
<% end %> <% end %>
</ul> </table>
<%= paginate @officials %> <%= paginate @officials %>

View File

@@ -4,18 +4,22 @@
<h3><%= page_entries_info @users %></h3> <h3><%= page_entries_info @users %></h3>
<ul class="admin-list"> <table>
<% @users.each do |user| %> <% @users.each do |user| %>
<li> <tr>
<td>
<%= link_to user.name, edit_admin_official_path(user) %> <%= link_to user.name, edit_admin_official_path(user) %>
<span class="bullet">&nbsp;&bull;&nbsp;</span> </td>
<td>
<span class="label round level-<%= user.official_level %>"> <span class="label round level-<%= user.official_level %>">
<%= user.official_position %> <%= user.official_position %>
</span> </span>
<span class="bullet">&nbsp;&bull;&nbsp;</span> (<%= t("admin.officials.level_#{user.official_level}") %>)
<span class="level"><%= t("admin.officials.level_#{user.official_level}") %></span> </td>
<td class="text-right">
<%= link_to user.official? ? t("admin.officials.search.edit_official") : t("admin.officials.search.make_official"), edit_admin_official_path(user), class: "button small float-right" %> <%= link_to user.official? ? t("admin.officials.search.edit_official") : t("admin.officials.search.make_official"),
</li> edit_admin_official_path(user), class: "button hollow" %>
</td>
</tr>
<% end %> <% end %>
</ul> </table>

View File

@@ -22,12 +22,12 @@
<% @organizations.each do |organization| %> <% @organizations.each do |organization| %>
<% hidden += 1 and next if organization.user.nil? || organization.user.hidden? %> <% hidden += 1 and next if organization.user.nil? || organization.user.hidden? %>
<tr id="<%= dom_id(organization) %>"> <tr id="<%= dom_id(organization) %>">
<td><%= organization.name %></td> <td><p><%= organization.name %></p></td>
<td><%= organization.email %></td> <td><p><%= organization.email %></p></td>
<td><%= organization.phone_number %></td> <td><p><%= organization.phone_number %></p></td>
<td><%= organization.responsible_name %></td> <td><p><%= organization.responsible_name %></p></td>
<% if organization.verified? %> <% if organization.verified? %>
<td class="verified"> <td class="verified text-center">
<span class="icon-check"></span> <span class="icon-check"></span>
<%= t("admin.organizations.index.verified") %> <%= t("admin.organizations.index.verified") %>
</td> </td>
@@ -36,20 +36,21 @@
<td> <td>
<%= link_to t("admin.organizations.index.verify"), <%= link_to t("admin.organizations.index.verify"),
verify_admin_organization_path(organization, request.query_parameters), verify_admin_organization_path(organization, request.query_parameters),
method: :put, class: "button small success" method: :put, class: "button success expanded"
%> %>
</td> </td>
<% end %> <% end %>
<% if organization.rejected? %> <% if organization.rejected? %>
<td class="rejected"> <td class="rejected text-center">
<span class="icon-x"></span> <span class="icon-x"></span>
<%= t("admin.organizations.index.rejected") %> <%= t("admin.organizations.index.rejected") %>
</td> </td>
<% end %> <% end %>
<% if can? :reject, organization %> <% if can? :reject, organization %>
<td><%= link_to t("admin.organizations.index.reject"), <td>
<%= link_to t("admin.organizations.index.reject"),
reject_admin_organization_path(organization, request.query_parameters), reject_admin_organization_path(organization, request.query_parameters),
method: :put, class: "button small alert" method: :put, class: "button hollow alert expanded"
%> %>
</td> </td>
<% end %> <% end %>
@@ -57,6 +58,10 @@
<% end %> <% end %>
</table> </table>
<%= t("admin.organizations.index.hidden_count", count: hidden) if hidden > 0 %> <% if hidden > 0 %>
<div class="callout primary">
<%= t("admin.organizations.index.hidden_count_html", count: hidden) %>
</div>
<% end %>
<%= paginate @organizations %> <%= paginate @organizations %>

View File

@@ -18,12 +18,12 @@
<table id="search-results"> <table id="search-results">
<% @organizations.each do |organization| %> <% @organizations.each do |organization| %>
<tr> <tr>
<td><%= organization.name %></td> <td><p><%= organization.name %></p></td>
<td><%= organization.email %></td> <td><p><%= organization.email %></p></td>
<td><%= organization.phone_number %></td> <td><p><%= organization.phone_number %></p></td>
<td><%= organization.responsible_name %></td> <td><p><%= organization.responsible_name %></p></td>
<% if organization.verified? %> <% if organization.verified? %>
<td class="verified"> <td class="verified text-center">
<span class="icon-check"></span> <span class="icon-check"></span>
<%= t("admin.organizations.index.verified") %> <%= t("admin.organizations.index.verified") %>
</td> </td>
@@ -32,12 +32,12 @@
<td> <td>
<%= link_to t("admin.organizations.index.verify"), <%= link_to t("admin.organizations.index.verify"),
verify_admin_organization_path(organization, request.query_parameters), verify_admin_organization_path(organization, request.query_parameters),
method: :put, class: "button small success" method: :put, class: "button success expanded"
%> %>
</td> </td>
<% end %> <% end %>
<% if organization.rejected? %> <% if organization.rejected? %>
<td class="rejected"> <td class="rejected text-center">
<span class="icon-x"></span> <span class="icon-x"></span>
<%= t("admin.organizations.index.rejected") %> <%= t("admin.organizations.index.rejected") %>
</td> </td>
@@ -45,7 +45,7 @@
<% if can? :reject, organization %> <% if can? :reject, organization %>
<td><%= link_to t("admin.organizations.index.reject"), <td><%= link_to t("admin.organizations.index.reject"),
reject_admin_organization_path(organization, request.query_parameters), reject_admin_organization_path(organization, request.query_parameters),
method: :put, class: "button small alert" method: :put, class: "button hollow alert expanded"
%> %>
</td> </td>
<% end %> <% end %>

View File

@@ -22,19 +22,17 @@
<p><%= proposal.question %></p> <p><%= proposal.question %></p>
</div> </div>
</td> </td>
<td> <td class="text-right">
<%= link_to t("admin.actions.restore"), <%= link_to t("admin.actions.restore"),
restore_admin_proposal_path(proposal, request.query_parameters), restore_admin_proposal_path(proposal, request.query_parameters),
method: :put, method: :put,
data: { confirm: t("admin.actions.confirm") }, data: { confirm: t("admin.actions.confirm") },
class: "button small success no-margin" %> class: "button hollow on-hover-block" %>
</td>
<td>
<% unless proposal.confirmed_hide? %> <% unless proposal.confirmed_hide? %>
<%= link_to t("admin.actions.confirm_hide"), <%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_proposal_path(proposal, request.query_parameters), confirm_hide_admin_proposal_path(proposal, request.query_parameters),
method: :put, method: :put,
class: "button small warning float-right" %> class: "button hollow warning on-hover-block" %>
<% end %> <% end %>
</td> </td>
</tr> </tr>

View File

@@ -1,34 +1,97 @@
<h2><%= t("admin.settings.index.title") %></h2> <h2><%= t("admin.settings.index.title") %></h2>
<ul class="admin-list"> <table>
<tbody>
<% @settings.each do |setting| %> <% @settings.each do |setting| %>
<li> <tr>
<td class="small-12 medium-4">
<strong><%= t("settings.#{setting.key}") %></strong> <strong><%= t("settings.#{setting.key}") %></strong>
</td>
<td class="small-12 medium-8">
<%= form_for(setting, url: admin_setting_path(setting), html: { id: "edit_#{dom_id(setting)}"}) do |f| %>
<div class="small-12 medium-6 large-9 column">
<%= f.text_area :value, label: false, id: dom_id(setting), lines: 1 %>
</div>
<div class="small-12 medium-6 large-3 column">
<%= f.submit(t('admin.settings.index.update_setting'), class: "button hollow expanded") %>
</div>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<h2><%= t("admin.settings.index.feature_flags") %></h2>
<table>
<tbody>
<% @feature_flags.each do |feature_flag| %>
<tr>
<td>
<strong><%= t("settings.#{feature_flag.key}") %></strong>
</td>
<td>
<%= feature_flag.enabled? ? t("admin.settings.index.features.enabled") : t("admin.settings.index.features.disabled") %>
</td>
<td class="text-right">
<%= form_for(feature_flag, url: admin_setting_path(feature_flag), html: { id: "edit_#{dom_id(feature_flag)}"}) do |f| %>
<%= f.hidden_field :value, id: dom_id(feature_flag), value: (feature_flag.enabled? ? "" : "active") %>
<%= f.submit(t("admin.settings.index.features.#{feature_flag.enabled? ? 'disable' : 'enable'}"),
class: "button expanded #{feature_flag.enabled? ? 'hollow alert' : 'success'}",
data: {confirm: t("admin.actions.confirm")}) %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% if @banner_styles.present? %>
<h2><%= t("admin.settings.index.banners") %></h2>
<table>
<tbody>
<% @banner_styles.each do |setting| %>
<tr>
<td>
<strong><%= t("settings.#{setting.key}") %></strong>
</td>
<td>
<%= form_for(setting, url: admin_setting_path(setting), html: { id: "edit_#{dom_id(setting)}"}) do |f| %>
<%= f.text_area :value, label: false, id: dom_id(setting), lines: 1 %>
<%= f.submit(t('admin.settings.index.update_setting'), class: "button hollow") %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
<% if @banner_imgs.present?%>
<h2><%= t("admin.settings.index.banner_imgs") %></h2>
<table>
<tbody>
<% @banner_imgs.each do |setting| %>
<tr>
<td>
<strong><%= t("settings.#{setting.key}") %></strong>
</td>
<td>
<%= form_for(setting, url: admin_setting_path(setting), html: { id: "edit_#{dom_id(setting)}"}) do |f| %> <%= form_for(setting, url: admin_setting_path(setting), html: { id: "edit_#{dom_id(setting)}"}) do |f| %>
<%= f.text_area :value, label: false, id: dom_id(setting), lines: 1 %> <%= f.text_area :value, label: false, id: dom_id(setting), lines: 1 %>
<%= f.submit(t('admin.settings.index.update_setting'), class: "button small success") %> <%= f.submit(t('admin.settings.index.update_setting'), class: "button small success") %>
<% end %> <% end %>
</li> </td>
</tr>
<% end %> <% end %>
</ul> </tbody>
</table>
<h2><%= t("admin.settings.index.feature_flags") %></h2>
<ul class="admin-list">
<% @feature_flags.each do |feature_flag| %>
<li>
<strong><%= t("settings.#{feature_flag.key}") %></strong>
<div>
<%= feature_flag.enabled? ? t("admin.settings.index.features.enabled") : t("admin.settings.index.features.disabled") %>
<div>
<%= form_for(feature_flag, url: admin_setting_path(feature_flag), html: { id: "edit_#{dom_id(feature_flag)}"}) do |f| %>
<%= f.hidden_field :value, id: dom_id(feature_flag), value: (feature_flag.enabled? ? "" : "active") %>
<%= f.submit(t("admin.settings.index.features.#{feature_flag.enabled? ? 'disable' : 'enable'}"), class: "button small #{feature_flag.enabled? ? 'warning' : 'success'}", data: {confirm: t("admin.actions.confirm")}) %>
<% end %> <% end %>
</li>
<% end %>
</ul>

View File

@@ -4,7 +4,7 @@
<%= text_field_tag :search, "", placeholder: t("admin.shared.proposal_search.placeholder") %> <%= text_field_tag :search, "", placeholder: t("admin.shared.proposal_search.placeholder") %>
</div> </div>
<div class="form-inline small-12 medium-6 column"> <div class="form-inline small-12 medium-6 column">
<%= f.submit t("admin.shared.proposal_search.button"), class: "button success" %> <%= f.submit t("admin.shared.proposal_search.button"), class: "button" %>
</div> </div>
</div> </div>
<% end %> <% end %>

View File

@@ -4,7 +4,7 @@
<%= text_field_tag :search, "", placeholder: t("admin.shared.spending_proposal_search.placeholder") %> <%= text_field_tag :search, "", placeholder: t("admin.shared.spending_proposal_search.placeholder") %>
</div> </div>
<div class="form-inline small-12 medium-3 column end"> <div class="form-inline small-12 medium-3 column end">
<%= f.submit t("admin.shared.spending_proposal_search.button"), class: "button success expanded" %> <%= f.submit t("admin.shared.spending_proposal_search.button"), class: "button" %>
</div> </div>
</div> </div>
<% end %> <% end %>

View File

@@ -0,0 +1,21 @@
<%= render 'shared/back_link' %>
<h2><%= t("admin.stats.direct_messages.title")%></h2>
<div class="stats">
<div class="row stats-numbers">
<div class="small-12 medium-3 column">
<p class="featured">
<%= t("admin.stats.direct_messages.total") %><br>
<span id="direct_messages_count" class="number"><%= @direct_messages %></span>
</p>
</div>
<div class="small-12 medium-6 column end">
<p>
<%= t("admin.stats.direct_messages.users_who_have_sent_message") %><br>
<span id="users_who_have_sent_message_count" class="number"><%= @users_who_have_sent_message %></span>
</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,41 @@
<%= render 'shared/back_link' %>
<h2><%= t("admin.stats.proposal_notifications.title")%></h2>
<div class="stats">
<div class="row stats-numbers">
<div class="small-12 medium-3 column">
<p class="featured">
<%= t("admin.stats.proposal_notifications.total") %><br>
<span id="proposal_notifications_count" class="number">
<%= @proposal_notifications.count %>
</span>
</p>
</div>
<div class="small-12 medium-6 column end">
<p>
<%= t("admin.stats.proposal_notifications.proposals_with_notifications") %><br>
<span id="proposals_with_notifications_count" class="number">
<%= @proposals_with_notifications %>
</span>
</p>
</div>
</div>
</div>
<table id="proposal_notifications">
<tbody>
<% @proposal_notifications.each do |notification| %>
<tr class="proposal_notification">
<td>
<h3>
<%= notification.title %>
<small><%= link_to notification.proposal.title, proposal_path(notification.proposal) %></small>
</h3>
<p><%= notification.body %></p>
</td>
</tr>
<% end %>
</tbody>
</table>

View File

@@ -1,10 +1,20 @@
<% content_for :head do %> <% content_for :head do %>
<%= javascript_include_tag "stat_graphs", 'data-turbolinks-track' => true %> <%= javascript_include_tag "stat_graphs", 'data-turbolinks-track' => true %>
<% end %> <% end %>
<div class="stats row-full"> <div class="stats">
<div class="row"> <div class="row">
<div class="small-12 column"> <div class="small-12 column">
<h1><%= t "admin.stats.show.stats_title" %></h1> <h1 class="inline-block"><%= t "admin.stats.show.stats_title" %></h1>
<div class="float-right clear">
<%= link_to t("admin.stats.show.direct_messages"),
direct_messages_admin_stats_path, class: "button hollow" %>
<%= link_to t("admin.stats.show.proposal_notifications"),
proposal_notifications_admin_stats_path, class: "button hollow" %>
</div>
<div class="clear"></div>
<div class="row stats-numbers"> <div class="row stats-numbers">
<div class="small-12 medium-3 column"> <div class="small-12 medium-3 column">

View File

@@ -22,29 +22,29 @@
<h3><%= t("admin.tags.index.title") %>: <%= page_entries_info @tags %></h3> <h3><%= t("admin.tags.index.title") %>: <%= page_entries_info @tags %></h3>
<ul class="admin-list"> <table>
<% @tags.each do |tag| %> <% @tags.each do |tag| %>
<li> <tr>
<span class="tag"><%= tag.name %></span> <td>
<%= form_for(tag, <%= form_for(tag,
url: admin_tag_path(tag), url: admin_tag_path(tag),
as: :tag, as: :tag,
html: { id: "edit_tag_#{tag.id}", class: "text-right"}) do |f| %> html: { id: "edit_tag_#{tag.id}", class: "text-right"}) do |f| %>
<span class="float-left"> <span class="float-left text-left">
<strong><%= tag.name %></strong>
<%= f.label "featured_#{tag.id}" do %> <%= f.label "featured_#{tag.id}" do %>
<%= f.check_box :featured, title: t('admin.tags.mark_as_featured'), label: false, id: "tag_featured_#{tag.id}", class: "inline-block" %> <%= f.check_box :featured, title: t('admin.tags.mark_as_featured'), label: false, id: "tag_featured_#{tag.id}", class: "inline-block" %>
<span class="checkbox inline-block"><%= t("admin.tags.mark_as_featured") %></span> <span class="checkbox inline-block"><%= t("admin.tags.mark_as_featured") %></span>
<% end %> <% end %>
</span> </span>
<%= f.submit(t("admin.tags.update"), class: "button small success") %> <%= f.submit(t("admin.tags.update"), class: "button hollow on-hover") %>
<%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: "button hollow alert on-hover" %>
<%= link_to t("admin.tags.destroy"), admin_tag_path(tag), method: :delete, class: "delete" %>
<% end %> <% end %>
</li> </td>
</tr>
<% end %> <% end %>
</ul> </table>
<%= paginate @tags %> <%= paginate @tags %>

View File

@@ -4,25 +4,29 @@
<h3><%= page_entries_info @users %></h3> <h3><%= page_entries_info @users %></h3>
<ul class="admin-list"> <table>
<% @users.each do |user| %> <% @users.each do |user| %>
<li id="<%= dom_id(user) %>"> <tr id="<%= dom_id(user) %>">
<%= link_to user.name, admin_user_path(user) %> <td>
<p><%= link_to user.name, admin_user_path(user) %></p>
</td>
<td class="text-right">
<%= link_to t("admin.actions.restore"), <%= link_to t("admin.actions.restore"),
restore_admin_user_path(user, request.query_parameters), restore_admin_user_path(user, request.query_parameters),
method: :put, method: :put,
data: { confirm: t("admin.actions.confirm") }, data: { confirm: t("admin.actions.confirm") },
class: "button small success float-right" %> class: "button hollow on-hover" %>
<% unless user.confirmed_hide? %> <% unless user.confirmed_hide? %>
<%= link_to t("admin.actions.confirm_hide"), <%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_user_path(user, request.query_parameters), confirm_hide_admin_user_path(user, request.query_parameters),
method: :put, method: :put,
class: "button small warning float-right" %> class: "button hollow warning on-hover" %>
<% end %> <% end %>
</li> </td>
</tr>
<% end %> <% end %>
</ul> </table>
<%= paginate @users %> <%= paginate @users %>

View File

@@ -1,3 +1,5 @@
<%= render 'shared/back_link' %>
<h2><%= t("admin.users.show.title", user: @user.name) %></h2> <h2><%= t("admin.users.show.title", user: @user.name) %></h2>
<p> <p>
@@ -5,37 +7,33 @@
<strong><%= t("admin.users.show.registered_at") %></strong> <%= @user.confirmed_at %> | <strong><%= t("admin.users.show.registered_at") %></strong> <%= @user.confirmed_at %> |
<strong><%= t("admin.users.show.hidden_at") %></strong> <%= @user.hidden_at %> <strong><%= t("admin.users.show.hidden_at") %></strong> <%= @user.hidden_at %>
</p> </p>
<p>
<%= link_to t("admin.users.show.back"), admin_users_path,
class: "button small secondary" %>
</p>
<% if @debates.present? %> <% if @debates.present? %>
<h3><%= page_entries_info @debates %></h3> <h3><%= page_entries_info @debates %></h3>
<% end %> <% end %>
<ul class="admin-list"> <table>
<% @debates.each do |debate| %> <% @debates.each do |debate| %>
<li> <tr>
<td>
<%= link_to debate.title, debate_path(debate) %> <%= link_to debate.title, debate_path(debate) %>
</li> </td>
</tr>
<% end %> <% end %>
</ul> </table>
<% if @comments.present? %> <% if @comments.present? %>
<h3><%= page_entries_info @comments %></h3> <h3><%= page_entries_info @comments %></h3>
<% end %> <% end %>
<ul class="admin-list"> <table>
<% @comments.each do |comment| %> <% @comments.each do |comment| %>
<li id="<%= dom_id(comment) %>"> <tr id="<%= dom_id(comment) %>">
<div class="row"> <td>
<div class="small-12 medium-10 column">
<%= text_with_links comment.body %> <%= text_with_links comment.body %>
</div> </td>
</div> </tr>
</li>
<% end %> <% end %>
</ul> </table>
<%= paginate [@debates, @comments].sort_by {|x| x.size}.last %> <%= paginate [@debates, @comments].sort_by {|x| x.size}.last %>

View File

@@ -1,12 +1,16 @@
<h3><%= t('admin.valuators.valuator.user_found') %>:</h3> <div class="small-12 column">
<div class="row"> <h3><%= t('admin.valuators.valuator.user_found') %></h3>
<div class="small-12 medium-12 column">
<h4> <table>
<tr>
<td>
<%= valuator.name %> <%= valuator.name %>
<span class="bullet">&nbsp;&bull;&nbsp;</span> </td>
<td>
<%= valuator.email %> <%= valuator.email %>
</h4> </td>
</div> </tr>
</table>
<% unless @valuator.persisted? %> <% unless @valuator.persisted? %>
<%= form_for @valuator, url: admin_valuators_path do |f| %> <%= form_for @valuator, url: admin_valuators_path do |f| %>

View File

@@ -1,6 +1,6 @@
<h2><%= t("admin.valuators.index.title") %></h2> <h2><%= t("admin.valuators.index.title") %></h2>
<div class="row"> <div class="row">
<div class="column">
<%= form_tag search_admin_valuators_path, method: :get, remote: true do %> <%= form_tag search_admin_valuators_path, method: :get, remote: true do %>
<div class="small-12 medium-6 column"> <div class="small-12 medium-6 column">
<%= text_field_tag :email, '', placeholder: t('admin.valuators.search.email_placeholder') %> <%= text_field_tag :email, '', placeholder: t('admin.valuators.search.email_placeholder') %>
@@ -10,21 +10,27 @@
</div> </div>
<% end %> <% end %>
</div> </div>
</div>
<div id="search-result" class="row small"></div> <div id="search-result" class="row"></div>
<h3><%= page_entries_info @valuators %></h3> <h3><%= page_entries_info @valuators %></h3>
<ul id="valuators" class="admin-list">
<table id="valuators">
<% @valuators.each do |valuator| %> <% @valuators.each do |valuator| %>
<li> <tr>
<span><%= valuator.name %></span> <td>
<span class="bullet">&nbsp;&bull;&nbsp;</span> <%= valuator.name %>
<span><%= valuator.email %></span> </td>
<td>
<%= valuator.email %>
</td>
<td>
<% if valuator.description.present? %> <% if valuator.description.present? %>
<span class="bullet">&nbsp;&bull;&nbsp;</span> <%= valuator.description %>
<span><%= valuator.description %></span>
<% end %> <% end %>
</li> </td>
</tr>
<% end %> <% end %>
</ul> </table>
<%= paginate @valuators %> <%= paginate @valuators %>

View File

@@ -1,7 +1,4 @@
<%= link_to admin_spending_proposals_path, class: "back" do %> <%= render 'shared/back_link' %>
<span class="icon-angle-left"></span>
<%= t("shared.back") %>
<% end %>
<h2><%= t("admin.valuators.summary.title") %></h2> <h2><%= t("admin.valuators.summary.title") %></h2>

View File

@@ -1 +1 @@
$("#search-result").html("<h4><%= j t('admin.valuators.search.user_not_found') %></h4>"); $("#search-result").html("<div class=\"small-12 column\"><div class=\"callout alert\"><%= j t('admin.valuators.search.user_not_found') %></div></div>");

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