From a4dbd768ce35c5c3394cc1c1a93025f71da3ead2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Pereira?=
Date: Tue, 31 May 2016 19:57:29 +0200
Subject: [PATCH 01/41] Custom folder structure: initial documentation, code
and structure folders
---
CUSTOMIZE_ES.md | 214 ++++++++++++++++++++++++++
Gemfile | 2 +
Gemfile_custom | 5 +
app/assets/images/custom/.keep | 0
app/assets/javascripts/application.js | 1 +
app/assets/javascripts/custom.js | 7 +
app/assets/stylesheets/custom.scss | 5 +-
app/models/custom/.keep | 0
app/views/custom/.keep | 0
config/application.rb | 13 ++
config/application_custom.rb | 4 +
config/initializers/assets.rb | 4 +
config/locales/custom/.keep | 0
spec/models/custom/.keep | 0
14 files changed, 254 insertions(+), 1 deletion(-)
create mode 100644 CUSTOMIZE_ES.md
create mode 100644 Gemfile_custom
create mode 100644 app/assets/images/custom/.keep
create mode 100644 app/assets/javascripts/custom.js
create mode 100644 app/models/custom/.keep
create mode 100644 app/views/custom/.keep
create mode 100644 config/application_custom.rb
create mode 100644 config/locales/custom/.keep
create mode 100644 spec/models/custom/.keep
diff --git a/CUSTOMIZE_ES.md b/CUSTOMIZE_ES.md
new file mode 100644
index 000000000..71c3701e4
--- /dev/null
+++ b/CUSTOMIZE_ES.md
@@ -0,0 +1,214 @@
+# Personalización
+
+Puedes modificar consul y ponerle tu propia imagen, para esto debes primero hacer un fork de https://github.com/consul/consul creando un repositorio nuevo en Github. Puedes usar otro servicio como Gitlab, pero no te olvides de poner el enlace en el footer a tu repositorio en cumplimiento con la licencia de este proyecto (GPL Affero 3).
+
+Hemos creado una estructura específica donde puedes sobreescribir y personalizar la aplicación para que puedas actualizar sin que tengas problemas al hacer merge y se sobreescriban por error tus cambios. Intentamos que Consul sea una aplicación Ruby on Rails lo más plain vanilla posible para facilitar el acceso de nuevas desarrolladoras.
+
+## Ficheros y directorios especiales
+
+Para adaptarlo puedes hacerlo a través de los directorios que están en custom dentro de:
+
+* config/locales/custom/
+* app/assets/images/custom/
+* app/views/custom/
+* app/controllers/custom/
+* app/models/custom/
+
+Aparte de estos directorios también cuentas con ciertos ficheros para:
+
+* app/assets/stylesheets/custom.css
+* app/assets/javascripts/custom.js
+* Gemfile_custom
+* config/application.custom.rb
+
+### Internacionalización
+
+Si quieres modificar algún texto de la web deberías encontrarlos en los ficheros formato YML disponibles en *config/locales/*. Puedes leer la [guía de internacionalización](http://guides.rubyonrails.org/i18n.html) de Ruby on Rails sobre como funciona este sistema.
+
+Las adaptaciones los debes poner en el directorio *config/locales/custom/*, recomendamos poner solo los textos que quieras personalizar. Por ejemplo si quieres personalizar el texto de "Ayuntamiento de Madrid, 2016" que se encuentra en el footer en todas las páginas, primero debemos ubicar en que plantilla se encuentra (app/views/layouts/_footer.html.erb), vemos que en el código pone lo siguiente:
+```
+<%= t("layouts.footer.copyright", year: Time.now.year) %>
+```
+
+Y que en el fichero config/locales/es.yml sigue esta estructura (solo ponemos lo relevante para este caso):
+
+```
+es:
+ layouts:
+ footer:
+ copyright: Ayuntamiento de Madrid, %{year}
+
+```
+
+Si creamos el fichero config/locales/custom/es.yml y modificamos "Ayuntamiento de Madrid" por el nombre de la organización que se este haciendo la modificación. Recomendamos directamente copiar los ficheros config/locales/ e ir revisando y corrigiendo las que querramos, borrando las líneas que no querramos traducir.
+
+### Imágenes
+
+Si quieres sobreescribir alguna imagen debes primero fijarte el nombre que tiene, por defecto se encuentran en *app/assets/images*. Por ejemplo si quieres modificar *app/assets/images/logo_header.png* debes poner otra con ese mismo nombre en el directorio app/assets/images/custom. Los iconos que seguramente quieras modificar son:
+
+* apple-touch-icon-200.png
+* icon_home.png
+* logo_email.png
+* logo_header.png
+* map.jpg
+* social-media-icon.png
+
+### Vistas (HTML)
+
+Si quieres modificar el HTML de alguna página puedes hacerlo copiando el HTML de *app/views* y poniendolo en *app/views/custom* respetando los subdirectorios que encuentres ahí. Por ejemplo si quieres modificar *app/views/pages/conditions.html* debes copiarlo y modificarla en app/views/custom/pages/conditions.html.erb
+
+### CSS
+
+Si quieres cambiar algun selector CSS (de las hojas de estilo) puedes hacerlo en el fichero *app/assets/stylesheets/custom.scss*. Por ejemplo si quieres cambiar el color del header (.top-links) puedes hacerlo agregando:
+
+```
+.top-links {
+ background: red;
+}
+```
+
+Usamos un preprocesador de CSS, [SASS, con la sintaxis SCSS](http://sass-lang.com/guide).
+
+### Javascript
+
+Si quieres agregar código Javascript puedes hacerlo en el fichero *app/assets/javascripts/custom.js". Por ejemplo si quieres que salga una alerta puedes poner lo siguiente:
+
+```
+$(function(){
+ alert('foobar');
+});
+```
+
+### Modelos
+
+Si quieres agregar modelos nuevos, o modificar o agregar métodos a uno ya existente puedes hacerlo en *app/models/custom*. En el caso de los modelos antiguos debes primero hacer un require de la dependencia.
+
+Por ejemplo en el caso del Ayuntamiento de Madrid se requiere comprobar que el código postal durante la verificación sigue un cierto formato (empieza con 280). Esto se realiza creando este fichero en *app/models/custom/verification/residence.rb*:
+
+```
+require_dependency Rails.root.join('app', 'models', 'verification', 'residence').to_s
+
+class Verification::Residence
+
+ validate :postal_code_in_madrid
+ validate :residence_in_madrid
+
+ def postal_code_in_madrid
+ errors.add(:postal_code, I18n.t('verification.residence.new.error_not_allowed_postal_code')) unless valid_postal_code?
+ end
+
+ def residence_in_madrid
+ return if errors.any?
+
+ unless residency_valid?
+ errors.add(:residence_in_madrid, false)
+ store_failed_attempt
+ Lock.increase_tries(user)
+ end
+ end
+
+ private
+
+ def valid_postal_code?
+ postal_code =~ /^280/
+ end
+
+end
+```
+
+No olvides poner los tests relevantes en *spec/models/custom*, siguiendo con el ejemplo pondriamos lo siguiente en *spec/models/custom/residence_spec.rb*:
+
+
+```
+require 'rails_helper'
+
+describe Verification::Residence do
+
+ let(:residence) { build(:verification_residence, document_number: "12345678Z") }
+
+ describe "verification" do
+
+ describe "postal code" do
+ it "should be valid with postal codes starting with 280" do
+ residence.postal_code = "28012"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(0)
+
+ residence.postal_code = "28023"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(0)
+ end
+
+ it "should not be valid with postal codes not starting with 280" do
+ residence.postal_code = "12345"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(1)
+
+ residence.postal_code = "13280"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(1)
+ expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered in the municipality of Madrid.")
+ end
+ end
+
+ end
+
+end
+```
+
+### Controladores
+
+TODO
+
+### Gemfile
+
+Para agregar librerías (gems) nuevas puedes hacerlo en el fichero *Gemfile_custom*. Por ejemplo si quieres agregar la gema [rails-footnotes](https://github.com/josevalim/rails-footnotes) debes hacerlo agregandole
+
+```
+gem 'rails-footnotes', '~> 4.0'
+```
+
+Y siguiendo el flujo clásico en Ruby on Rails (bundle install y seguir con los pasos específicos de la gema en la documentación)
+
+### application.rb
+
+Cuando necesites extender o modificar el *config/application.rb* puedes hacerlo a través del fichero *config/application_custom.rb*. Por ejemplo si quieres modificar el idioma por defecto al inglés pondrías lo siguiente:
+
+
+```
+module Consul
+ class Application < Rails::Application
+ config.i18n.default_locale = :en
+ config.i18n.available_locales = [:en, :es]
+ end
+end
+```
+
+Recuerda que para ver reflejado estos cambios debes reiniciar el servidor de desarrollo.
+
+### lib/
+
+TODO
+
+### public/
+
+TODO
+
+### Seeds
+
+TODO
+
+## Actualizar
+
+Te recomendamos que agregues el remote de consul para facilitar este proceso de merge:
+
+```
+$ git remote add consul https://github.com/consul/consul
+```
+
+Con esto puedes actualizarte con
+
+```
+git checkout -b consul_update
+git pull consul master
+```
diff --git a/Gemfile b/Gemfile
index 50b9e37e9..ca56313fc 100644
--- a/Gemfile
+++ b/Gemfile
@@ -94,3 +94,5 @@ group :development do
# Access an IRB console on exception pages or by using <%= console %> in views
gem 'web-console', '~> 3.0'
end
+
+eval_gemfile './Gemfile_custom'
diff --git a/Gemfile_custom b/Gemfile_custom
new file mode 100644
index 000000000..9d91e0680
--- /dev/null
+++ b/Gemfile_custom
@@ -0,0 +1,5 @@
+# Overrides and adds customized gems in this file
+# Read more on documentation:
+# * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#gemfile
+# * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#gemfile
+#
diff --git a/app/assets/images/custom/.keep b/app/assets/images/custom/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index a1b8dd70a..ca79ceb8b 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -45,6 +45,7 @@
//= require valuation_spending_proposal_form
//= require embed_video
//= require banners
+//= require custom
var initialize_modules = function() {
App.Comments.initialize();
diff --git a/app/assets/javascripts/custom.js b/app/assets/javascripts/custom.js
new file mode 100644
index 000000000..6c880b3a9
--- /dev/null
+++ b/app/assets/javascripts/custom.js
@@ -0,0 +1,7 @@
+// Overrides and adds customized javascripts in this file
+// Read more on documentation:
+// * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#javascript
+// * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#javascript
+//
+//
+
diff --git a/app/assets/stylesheets/custom.scss b/app/assets/stylesheets/custom.scss
index c764f4ad2..090eb0342 100644
--- a/app/assets/stylesheets/custom.scss
+++ b/app/assets/stylesheets/custom.scss
@@ -1,2 +1,5 @@
// Overrides and adds customized styles in this file
-//
\ No newline at end of file
+// Read more on documentation:
+// * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#css
+// * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#css
+//
diff --git a/app/models/custom/.keep b/app/models/custom/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/views/custom/.keep b/app/views/custom/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/config/application.rb b/config/application.rb
index 395251a52..3f2a0861a 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -1,3 +1,4 @@
+
require File.expand_path('../boot', __FILE__)
require 'rails/all'
@@ -34,5 +35,17 @@ module Consul
config.autoload_paths << Rails.root.join('lib')
config.time_zone = 'Madrid'
config.active_job.queue_adapter = :delayed_job
+
+ # Consul specific custom overrides
+ # Read more on documentation:
+ # * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md
+ # * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md
+ #
+ config.autoload_paths << "#{Rails.root}/app/controllers/custom"
+ config.autoload_paths << "#{Rails.root}/app/models/custom"
+ config.paths['app/views'].unshift(Rails.root.join('app', 'views', 'custom'))
+
end
end
+
+require "./config/application_custom.rb"
diff --git a/config/application_custom.rb b/config/application_custom.rb
new file mode 100644
index 000000000..b99944bc7
--- /dev/null
+++ b/config/application_custom.rb
@@ -0,0 +1,4 @@
+module Consul
+ class Application < Rails::Application
+ end
+end
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index a13ed5320..543b39fc9 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -13,3 +13,7 @@ Rails.application.config.assets.precompile += %w( ckeditor/* )
Rails.application.config.assets.precompile += %w( ie_lt9.js )
Rails.application.config.assets.precompile += %w( stat_graphs.js )
Rails.application.config.assets.precompile += %w( print.css )
+
+# Really ugly hack to putting app/assets/images/custom in front of app/assets/images
+images_path = Rails.application.config.assets.paths
+images_path = images_path.insert(0, Rails.root.join("app", "assets", "images", "custom").to_s)
diff --git a/config/locales/custom/.keep b/config/locales/custom/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/spec/models/custom/.keep b/spec/models/custom/.keep
new file mode 100644
index 000000000..e69de29bb
From 24a9d77e6471263e7656b11dd51ded3106d963dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9s=20Pereira?=
Date: Tue, 31 May 2016 19:57:37 +0200
Subject: [PATCH 02/41] Custom folder structure: verification residence for
Madrid
---
app/models/custom/verification/residence.rb | 29 ++++++++++++++++++
app/models/verification/residence.rb | 20 ------------
spec/models/custom/residence_spec.rb | 34 +++++++++++++++++++++
spec/models/residence_spec.rb | 23 --------------
4 files changed, 63 insertions(+), 43 deletions(-)
create mode 100644 app/models/custom/verification/residence.rb
create mode 100644 spec/models/custom/residence_spec.rb
diff --git a/app/models/custom/verification/residence.rb b/app/models/custom/verification/residence.rb
new file mode 100644
index 000000000..1cbc6f7ab
--- /dev/null
+++ b/app/models/custom/verification/residence.rb
@@ -0,0 +1,29 @@
+
+require_dependency Rails.root.join('app', 'models', 'verification', 'residence').to_s
+
+class Verification::Residence
+
+ validate :postal_code_in_madrid
+ validate :residence_in_madrid
+
+ def postal_code_in_madrid
+ errors.add(:postal_code, I18n.t('verification.residence.new.error_not_allowed_postal_code')) unless valid_postal_code?
+ end
+
+ def residence_in_madrid
+ return if errors.any?
+
+ unless residency_valid?
+ errors.add(:residence_in_madrid, false)
+ store_failed_attempt
+ Lock.increase_tries(user)
+ end
+ end
+
+ private
+
+ def valid_postal_code?
+ postal_code =~ /^280/
+ end
+
+end
diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb
index 5756af2b3..cc24bb7c8 100644
--- a/app/models/verification/residence.rb
+++ b/app/models/verification/residence.rb
@@ -16,8 +16,6 @@ class Verification::Residence
validate :allowed_age
validate :document_number_uniqueness
- validate :postal_code_in_madrid
- validate :residence_in_madrid
def initialize(attrs={})
self.date_of_birth = parse_date('date_of_birth', attrs)
@@ -45,20 +43,6 @@ class Verification::Residence
errors.add(:document_number, I18n.t('errors.messages.taken')) if User.where(document_number: document_number).any?
end
- def postal_code_in_madrid
- errors.add(:postal_code, I18n.t('verification.residence.new.error_not_allowed_postal_code')) unless valid_postal_code?
- end
-
- def residence_in_madrid
- return if errors.any?
-
- unless residency_valid?
- errors.add(:residence_in_madrid, false)
- store_failed_attempt
- Lock.increase_tries(user)
- end
- end
-
def store_failed_attempt
FailedCensusCall.create({
user: user,
@@ -97,8 +81,4 @@ class Verification::Residence
self.document_number = self.document_number.gsub(/[^a-z0-9]+/i, "").upcase unless self.document_number.blank?
end
- def valid_postal_code?
- postal_code =~ /^280/
- end
-
end
diff --git a/spec/models/custom/residence_spec.rb b/spec/models/custom/residence_spec.rb
new file mode 100644
index 000000000..ce0a95869
--- /dev/null
+++ b/spec/models/custom/residence_spec.rb
@@ -0,0 +1,34 @@
+require 'rails_helper'
+
+describe Verification::Residence do
+
+ let(:residence) { build(:verification_residence, document_number: "12345678Z") }
+
+ describe "verification" do
+
+ describe "postal code" do
+ it "should be valid with postal codes starting with 280" do
+ residence.postal_code = "28012"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(0)
+
+ residence.postal_code = "28023"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(0)
+ end
+
+ it "should not be valid with postal codes not starting with 280" do
+ residence.postal_code = "12345"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(1)
+
+ residence.postal_code = "13280"
+ residence.valid?
+ expect(residence.errors[:postal_code].size).to eq(1)
+ expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered in the municipality of Madrid.")
+ end
+ end
+
+ end
+
+end
diff --git a/spec/models/residence_spec.rb b/spec/models/residence_spec.rb
index ce151eaee..968a80e62 100644
--- a/spec/models/residence_spec.rb
+++ b/spec/models/residence_spec.rb
@@ -30,29 +30,6 @@ describe Verification::Residence do
expect(residence.errors[:date_of_birth]).to include("You must be at least 16 years old")
end
- describe "postal code" do
- it "should be valid with postal codes starting with 280" do
- residence.postal_code = "28012"
- residence.valid?
- expect(residence.errors[:postal_code].size).to eq(0)
-
- residence.postal_code = "28023"
- residence.valid?
- expect(residence.errors[:postal_code].size).to eq(0)
- end
-
- it "should not be valid with postal codes not starting with 280" do
- residence.postal_code = "12345"
- residence.valid?
- expect(residence.errors[:postal_code].size).to eq(1)
-
- residence.postal_code = "13280"
- residence.valid?
- expect(residence.errors[:postal_code].size).to eq(1)
- expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered in the municipality of Madrid.")
- end
- end
-
it "should validate uniquness of document_number" do
user = create(:user)
residence.user = user
From f3e0626709a731f6d0ae5f95f232a59df739ac5c Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Tue, 12 Jul 2016 13:24:49 +0200
Subject: [PATCH 03/41] Adds text to notifications icons on header
---
app/views/devise/menu/_login_items.html.erb | 1 +
config/locales/en.yml | 1 +
config/locales/es.yml | 1 +
3 files changed, 3 insertions(+)
diff --git a/app/views/devise/menu/_login_items.html.erb b/app/views/devise/menu/_login_items.html.erb
index 55665708a..0ab28e2ee 100644
--- a/app/views/devise/menu/_login_items.html.erb
+++ b/app/views/devise/menu/_login_items.html.erb
@@ -1,6 +1,7 @@
<% if user_signed_in? %>
<%= link_to notifications_path, class: "notifications", accesskey: "n" do %>
+ <%= t("layouts.header.notifications") %>
<% if current_user.notifications_count > 0 %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 05153d714..86e4306a0 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -198,6 +198,7 @@ en:
more_information: More information
my_account_link: My account
my_activity_link: My activity
+ notifications: Notifications
new_notifications:
one: You have a new notification
other: You have %{count} new notifications
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 9391da3bf..e4ffff6c3 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -198,6 +198,7 @@ es:
more_information: Más información
my_account_link: Mi cuenta
my_activity_link: Mi actividad
+ notifications: Notificaciones
new_notifications:
one: Tienes una nueva notificación
other: Tienes %{count} notificaciones nuevas
From 77b99c1b5c0d0548ece8cf1cae7128b321cdaaf3 Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Tue, 12 Jul 2016 13:48:55 +0200
Subject: [PATCH 04/41] Adds text to icons like and unlike on debates
---
app/views/debates/_votes.html.erb | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/app/views/debates/_votes.html.erb b/app/views/debates/_votes.html.erb
index 9ac6638d6..4c5f5a9b7 100644
--- a/app/views/debates/_votes.html.erb
+++ b/app/views/debates/_votes.html.erb
@@ -3,7 +3,9 @@
<%= link_to vote_debate_path(debate, value: 'yes'),
class: "like #{voted_classes[:in_favor]}", title: t('votes.agree'), method: "post", remote: true do %>
-
+
+ <%= t('votes.agree') %>
+
<%= votes_percentage('likes', debate) %>
<% end %>
@@ -12,7 +14,9 @@
<%= link_to vote_debate_path(debate, value: 'no'), class: "unlike #{voted_classes[:against]}", title: t('votes.disagree'), method: "post", remote: true do %>
-
+
+ <%= t('votes.disagree') %>
+
<%= votes_percentage('dislikes', debate) %>
<% end %>
From 62a7b3238911e4218c5a4bd380f94a11eb4a9efc Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Tue, 12 Jul 2016 13:55:52 +0200
Subject: [PATCH 05/41] Adds texts to icons on comments votes
---
app/views/comments/_votes.html.erb | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/app/views/comments/_votes.html.erb b/app/views/comments/_votes.html.erb
index 20fc2d1cf..8ee315e35 100644
--- a/app/views/comments/_votes.html.erb
+++ b/app/views/comments/_votes.html.erb
@@ -7,7 +7,9 @@
<% if can?(:vote, comment) %>
<%= link_to vote_comment_path(comment, value: 'yes'),
method: "post", remote: true do %>
-
+
+ <%= t('votes.agree') %>
+
<% end %>
<% else %>
@@ -19,7 +21,9 @@
<% if can?(:vote, comment) %>
<%= link_to vote_comment_path(comment, value: 'no'),
method: "post", remote: true do %>
-
+
+ <%= t('votes.disagree') %>
+
<% end %>
<% else %>
From c3d70f6e950de6b1cdbcb07212246fec15685657 Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Thu, 14 Jul 2016 18:02:27 +0200
Subject: [PATCH 06/41] Adds text for show comment children
---
app/views/comments/_comment.html.erb | 1 +
config/locales/en.yml | 1 +
config/locales/es.yml | 1 +
3 files changed, 3 insertions(+)
diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb
index 7b5ff4b7d..bf8bfb50d 100644
--- a/app/views/comments/_comment.html.erb
+++ b/app/views/comments/_comment.html.erb
@@ -74,6 +74,7 @@
<% if comment.children.size > 0 %>
<%= link_to "", class: "js-toggle-children relative", data: {'id': "#{dom_id(comment)}"} do %>
+ <%= t("shared.show") %>
<%= t("comments.comment.responses", count: comment.children.size) %>
<% end %>
<% else %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 86e4306a0..cc44b5592 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -414,6 +414,7 @@ en:
flag: Flag as inappropriate
print:
print_button: Print this info
+ show: Show
suggest:
debate:
found:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index e4ffff6c3..f60785119 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -414,6 +414,7 @@ es:
flag: Denunciar como inapropiado
print:
print_button: Imprimir esta información
+ show: Mostrar
suggest:
debate:
found:
From a30d9218d49f8236ac70af238e4f26b8a340e119 Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Thu, 14 Jul 2016 18:07:45 +0200
Subject: [PATCH 07/41] Deletes alt text for decorative images
---
app/views/welcome/index.html.erb | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb
index c7ed38d8c..978ff489c 100644
--- a/app/views/welcome/index.html.erb
+++ b/app/views/welcome/index.html.erb
@@ -21,24 +21,24 @@
- <%= image_tag("icon_home_debate.png", size: "168x168", alt: t("welcome.debates.alt"), title: t("welcome.debates.title")) %>
+ <%= image_tag("icon_home_debate.png", size: "168x168", alt: "", title: t("welcome.debates.title")) %>
<%= t("welcome.debates.title") %>
<%= t("welcome.debates.description") %>
- <%= image_tag("icon_home_proposal.png", size: "168x168", alt: t("welcome.proposal.alt"), title: t("welcome.proposal.title")) %>
+ <%= image_tag("icon_home_proposal.png", size: "168x168", alt: "", title: t("welcome.proposal.title")) %>
<%= t("welcome.proposal.title") %>
<%= t("welcome.proposal.description") %>
- <%= image_tag("icon_home_decide.png", size: "168x168", alt: t("welcome.decide.alt"), title: t("welcome.decide.title")) %>
+ <%= image_tag("icon_home_decide.png", size: "168x168", alt: "", title: t("welcome.decide.title")) %>
<%= t("welcome.decide.title") %>
<%= t("welcome.decide.description") %>
- <%= image_tag("icon_home_do.png", size: "168x168", alt: t("welcome.do.alt"), title: t("welcome.do.title")) %>
+ <%= image_tag("icon_home_do.png", size: "168x168", alt: "", title: t("welcome.do.title")) %>
<%= t("welcome.do.title") %>
<%= t("welcome.do.description") %>
From 3f6dc4ff5e568b5699d91f6bf9f6aef9662ee713 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Tue, 19 Jul 2016 16:00:42 +0200
Subject: [PATCH 08/41] updates Readme with reference to Customization
instructions
---
README.md | 4 ++++
README_ES.md | 3 +++
2 files changed, 7 insertions(+)
diff --git a/README.md b/README.md
index 7a92401f3..27162bfd7 100644
--- a/README.md
+++ b/README.md
@@ -62,6 +62,10 @@ But for some actions like voting, you will need a verified user, the seeds file
**user:** verified@consul.dev
**pass:** 12345678
+### Customization
+
+See [CUSTOMIZE_ES.md](CUSTOMIZE_ES.md)
+
### OAuth
To test authentication services with external OAuth suppliers - right now Twitter, Facebook and Google - you'll need to create an "application" in each of the supported platforms and set the *key* and *secret* provided in your *secrets.yml*
diff --git a/README_ES.md b/README_ES.md
index 489412299..d8c394680 100644
--- a/README_ES.md
+++ b/README_ES.md
@@ -61,6 +61,9 @@ Pero para ciertas acciones, como apoyar, necesitarás un usuario verificado, el
**user:** verified@consul.dev
**pass:** 12345678
+### Customización
+
+Ver fichero [CUSTOMIZE_ES.md](CUSTOMIZE_ES.md)
### OAuth
From c42a041d3af84d4b4030b044524e82aa2f2951f0 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Tue, 19 Jul 2016 16:20:45 +0200
Subject: [PATCH 09/41] fixes specs
---
spec/models/custom/residence_spec.rb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/spec/models/custom/residence_spec.rb b/spec/models/custom/residence_spec.rb
index ce0a95869..81c0b2e9b 100644
--- a/spec/models/custom/residence_spec.rb
+++ b/spec/models/custom/residence_spec.rb
@@ -1,10 +1,10 @@
require 'rails_helper'
describe Verification::Residence do
-
+
let(:residence) { build(:verification_residence, document_number: "12345678Z") }
- describe "verification" do
+ describe "verification" do
describe "postal code" do
it "should be valid with postal codes starting with 280" do
@@ -25,7 +25,7 @@ describe Verification::Residence do
residence.postal_code = "13280"
residence.valid?
expect(residence.errors[:postal_code].size).to eq(1)
- expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered in the municipality of Madrid.")
+ expect(residence.errors[:postal_code]).to include("In order to be verified, you must be registered.")
end
end
From 6d2f28b13d06d9ebe1362994e949e7ca76ac3d51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Wed, 20 Jul 2016 13:16:59 +0200
Subject: [PATCH 10/41] removes unused i18n entries
---
config/locales/en.yml | 4 ----
config/locales/es.yml | 4 ----
2 files changed, 8 deletions(-)
diff --git a/config/locales/en.yml b/config/locales/en.yml
index cc44b5592..3a16722dc 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -566,19 +566,15 @@ en:
not_voting_allowed: Voting phase is closed
welcome:
debates:
- alt: Icon debates
description: For meeting, discussing and sharing the things that matter to us in our city.
title: Debates
decide:
- alt: Icon decide
description: The public decides if it accepts or rejects the most supported proposals.
title: You decide
do:
- alt: Icon it gets done
description: If the proposal is accepted by the majority, the City Council accepts it as its own and it gets done.
title: It gets done
proposal:
- alt: Icon propose
description: Open space for citizen proposals about the kind of city we want to live in.
title: You propose
verification:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index f60785119..993ee8e95 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -566,19 +566,15 @@ es:
not_voting_allowed: El periodo de votación está cerrado.
welcome:
debates:
- alt: Icono debates
description: Encontrarnos, debatir y compartir lo que nos parece importante en nuestra ciudad.
title: Debates
decide:
- alt: Icono decides
description: La ciudadanía decide si acepta o rechaza las propuestas más apoyadas.
title: Decides
do:
- alt: Icono se hace
description: Si la propuesta es aceptada mayoritariamente, el Ayuntamiento la asume como propia y se hace.
title: Se hace
proposal:
- alt: Icono propones
description: Espacio abierto para propuestas ciudadanas sobre el tipo de ciudad en el que queremos vivir.
title: Propones
verification:
From 2f392a28c3b0a6be664ef02c8ce37185aa45b667 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Mon, 25 Jul 2016 13:57:22 +0200
Subject: [PATCH 11/41] updates dependencies sass-rails & sprockets
---
Gemfile.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Gemfile.lock b/Gemfile.lock
index ad24ae9ec..5ccd7f8ba 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -350,7 +350,7 @@ GEM
safely_block (0.1.1)
errbase
sass (3.4.22)
- sass-rails (5.0.5)
+ sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
@@ -375,7 +375,7 @@ GEM
spring (1.7.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
- sprockets (3.6.3)
+ sprockets (3.7.0)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-es6 (0.9.0)
From baddfdb3d166f6d804d8e5381bc9655c04c905c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baza=CC=81n?=
Date: Wed, 20 Jul 2016 13:15:02 +0200
Subject: [PATCH 12/41] adds phase scopes to budget
---
app/models/budget.rb | 3 +++
1 file changed, 3 insertions(+)
diff --git a/app/models/budget.rb b/app/models/budget.rb
index ea22a4615..d642e7d0c 100644
--- a/app/models/budget.rb
+++ b/app/models/budget.rb
@@ -10,6 +10,9 @@ class Budget < ActiveRecord::Base
has_many :headings, through: :groups
has_many :investments, through: :headings
+ scope :open, -> { where.not(phase: "finished") }
+ scope :finished, -> { where(phase: "finished") }
+
def on_hold?
phase == "on_hold"
end
From 1ad78d599e0f30ab5e79f1cf7ffa712c65c96171 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Thu, 28 Jul 2016 12:36:39 +0200
Subject: [PATCH 13/41] adds admin budgets index
---
app/controllers/admin/budgets_controller.rb | 9 +++
app/views/admin/budgets/index.html.erb | 25 +++++++
config/locales/activerecord.en.yml | 3 +
config/locales/activerecord.es.yml | 3 +
config/locales/admin.en.yml | 8 +++
config/locales/admin.es.yml | 8 +++
config/locales/en.yml | 7 ++
config/locales/es.yml | 7 ++
config/routes.rb | 7 ++
db/schema.rb | 2 +-
spec/features/admin/budgets_spec.rb | 79 +++++++++++++++++++++
11 files changed, 157 insertions(+), 1 deletion(-)
create mode 100644 app/controllers/admin/budgets_controller.rb
create mode 100644 app/views/admin/budgets/index.html.erb
create mode 100644 spec/features/admin/budgets_spec.rb
diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
new file mode 100644
index 000000000..a2f92a39e
--- /dev/null
+++ b/app/controllers/admin/budgets_controller.rb
@@ -0,0 +1,9 @@
+class Admin::BudgetsController < Admin::BaseController
+
+ has_filters %w{open finished}, only: :index
+
+ def index
+ @budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page])
+ end
+
+end
diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb
new file mode 100644
index 000000000..193b6a7ef
--- /dev/null
+++ b/app/views/admin/budgets/index.html.erb
@@ -0,0 +1,25 @@
+<%= t("admin.budgets.index.title") %>
+
+<%= link_to t("admin.budgets.index.new_link"),
+ new_admin_budget_path,
+ class: "button float-right margin-right" %>
+
+<%= render 'shared/filter_subnav', i18n_namespace: "admin.budgets.index" %>
+
+
+<%= page_entries_info @budgets %>
+
+
+ <% @budgets.each do |budget| %>
+
+
+ <%= link_to budget.name, admin_budget_path(budget) %>
+
+
+ <%= t("budget.phase.#{budget.phase}") %>
+
+
+ <% end %>
+
+
+<%= paginate @budgets %>
\ No newline at end of file
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 07791e53c..5a7a591bd 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -4,6 +4,9 @@ en:
activity:
one: "activity"
other: "activities"
+ budget:
+ one: "Participatory budget"
+ other: "Participatory budgets"
comment:
one: "Comment"
other: "Comments"
diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml
index d5b7f0005..ccd0240e8 100644
--- a/config/locales/activerecord.es.yml
+++ b/config/locales/activerecord.es.yml
@@ -4,6 +4,9 @@ es:
activity:
one: "actividad"
other: "actividades"
+ budget:
+ one: "Presupuesto participativo"
+ other: "Presupuestos participativos"
comment:
one: "Comentario"
other: "Comentarios"
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index 2f73f64d8..7d32e3291 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -60,6 +60,13 @@ en:
on_users: Users
title: Moderator activity
type: Type
+ budgets:
+ index:
+ title: Participatory budgets
+ new_link: Create new
+ filters:
+ open: Open
+ finished: Finished
comments:
index:
filter: Filter
@@ -96,6 +103,7 @@ en:
activity: Moderator activity
admin: Admin menu
banner: Manage banners
+ budgets: Participatory budgets
debate_topics: Debate topics
hidden_comments: Hidden comments
hidden_debates: Hidden debates
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 5aada1ce1..c5f0df247 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -58,6 +58,13 @@ es:
on_users: Usuarios
title: Actividad de los Moderadores
type: Tipo
+ budgets:
+ index:
+ title: Presupuestos participativos
+ new_link: Crear nuevo
+ filters:
+ open: Abiertos
+ finished: Terminados
comments:
index:
filter: Filtro
@@ -94,6 +101,7 @@ es:
activity: Actividad de moderadores
admin: Menú de administración
banner: Gestionar banners
+ budgets: Presupuestos participativos
debate_topics: Temas de debate
hidden_comments: Comentarios ocultos
hidden_debates: Debates ocultos
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 05153d714..fae75307f 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -33,6 +33,13 @@ en:
application:
close: Close
menu: Menu
+ budget:
+ phase:
+ on_hold: On hold
+ accepting: Accepting proposals
+ selecting: Selecting
+ balloting: Balloting
+ finished: Finished
comments:
comment:
admin: Administrator
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 9391da3bf..282340395 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -33,6 +33,13 @@ es:
application:
close: Cerrar
menu: Menú
+ budget:
+ phase:
+ on_hold: Pausa
+ accepting: Aceptando propuestas
+ selecting: Fase de selección
+ balloting: Fase de Votación
+ finished: Terminado
comments:
comment:
admin: Administrador
diff --git a/config/routes.rb b/config/routes.rb
index 22518f8c8..8cf94ea23 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -153,6 +153,13 @@ Rails.application.routes.draw do
get :summary, on: :collection
end
+ resources :budgets do
+ resources :budget_groups do
+ resources :budget_headings do
+ end
+ end
+ end
+
resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do
collection { get :search}
end
diff --git a/db/schema.rb b/db/schema.rb
index ee5b3ab6f..df58b15cb 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -210,10 +210,10 @@ ActiveRecord::Schema.define(version: 20160617172616) do
t.string "visit_id"
t.datetime "hidden_at"
t.integer "flags_count", default: 0
- t.datetime "ignored_flag_at"
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_up", default: 0
t.integer "cached_votes_down", default: 0
+ t.datetime "ignored_flag_at"
t.integer "comments_count", default: 0
t.datetime "confirmed_hide_at"
t.integer "cached_anonymous_votes_total", default: 0
diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb
new file mode 100644
index 000000000..8326a5dac
--- /dev/null
+++ b/spec/features/admin/budgets_spec.rb
@@ -0,0 +1,79 @@
+require 'rails_helper'
+
+feature 'Admin budgets' do
+
+ background do
+ admin = create(:administrator)
+ login_as(admin.user)
+ end
+
+ context "Feature flag" do
+
+ xscenario 'Disabled with a feature flag' do
+ Setting['feature.budgets'] = nil
+ expect{ visit admin_budgets_path }.to raise_exception(FeatureFlags::FeatureDisabled)
+ end
+
+ end
+
+ context "Index" do
+
+ scenario 'Displaying budgets' do
+ budget = create(:budget)
+ visit admin_budgets_path
+
+ expect(page).to have_content(budget.name)
+ expect(page).to have_content(I18n.t("budget.phase.#{budget.phase}"))
+ end
+
+ scenario 'Filters by phase' do
+ budget1 = create(:budget)
+ budget2 = create(:budget, :accepting)
+ budget3 = create(:budget, :selecting)
+ budget4 = create(:budget, :balloting)
+ budget5 = create(:budget, :finished)
+
+ visit admin_budgets_path
+ expect(page).to have_content(budget1.name)
+ expect(page).to have_content(budget2.name)
+ expect(page).to have_content(budget3.name)
+ expect(page).to have_content(budget4.name)
+ expect(page).to_not have_content(budget5.name)
+
+ click_link "Finished"
+ expect(page).to_not have_content(budget1.name)
+ expect(page).to_not have_content(budget2.name)
+ expect(page).to_not have_content(budget3.name)
+ expect(page).to_not have_content(budget4.name)
+ expect(page).to have_content(budget5.name)
+
+ click_link "Open"
+ expect(page).to have_content(budget1.name)
+ expect(page).to have_content(budget2.name)
+ expect(page).to have_content(budget3.name)
+ expect(page).to have_content(budget4.name)
+ expect(page).to_not have_content(budget5.name)
+ end
+
+
+ scenario "Current filter is properly highlighted" do
+ filters_links = {'open' => 'Open', 'finished' => 'Finished'}
+
+ visit admin_budgets_path
+
+ expect(page).to_not have_link(filters_links.values.first)
+ filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) }
+
+ filters_links.each_pair do |current_filter, link|
+ visit admin_budgets_path(filter: current_filter)
+
+ expect(page).to_not have_link(link)
+
+ (filters_links.keys - [current_filter]).each do |filter|
+ expect(page).to have_link(filters_links[filter])
+ end
+ end
+ end
+
+ end
+end
\ No newline at end of file
From a9c3629de7e77455042f6614040e1ec65b95363c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Thu, 28 Jul 2016 12:37:00 +0200
Subject: [PATCH 14/41] adds missing trait to testing factories
---
spec/factories.rb | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/spec/factories.rb b/spec/factories.rb
index 263900ecd..bca0c51e3 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -193,6 +193,10 @@ FactoryGirl.define do
currency_symbol "€"
phase 'on_hold'
+ trait :accepting do
+ phase 'accepting'
+ end
+
trait :selecting do
phase 'selecting'
end
From 958cfb1338500d0d5f32467ebb6878762dde1fe1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Thu, 28 Jul 2016 12:37:12 +0200
Subject: [PATCH 15/41] adds budgets to admin's menu
---
app/views/admin/_menu.html.erb | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb
index 7ea48b2c6..d1feaeb1e 100644
--- a/app/views/admin/_menu.html.erb
+++ b/app/views/admin/_menu.html.erb
@@ -35,6 +35,14 @@
<% end %>
+ <%# if feature?(:budgets) %>
+ >
+ <%= link_to admin_budgets_path do %>
+ <%= t("admin.menu.budgets") %>
+ <% end %>
+
+ <%# end %>
+
>
<%= link_to admin_banners_path do %>
<%= t("admin.menu.banner") %>
From 6bb09185e4db3c0ee5d74ed127b1930269459691 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Thu, 28 Jul 2016 12:40:57 +0200
Subject: [PATCH 16/41] makes i18n-tasks ignore filter keys in budgets
---
config/i18n-tasks.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index 250ed18f9..e24d3af0c 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -112,6 +112,7 @@ ignore_unused:
- 'admin.banners.index.filters.*'
- 'admin.debates.index.filter*'
- 'admin.proposals.index.filter*'
+ - 'admin.budgets.index.filter*'
- 'admin.spending_proposals.index.filter*'
- 'admin.organizations.index.filter*'
- 'admin.users.index.filter*'
From b69308b770781e054ec4c5c67b49b0ce6b54d5e9 Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Thu, 28 Jul 2016 13:04:30 +0200
Subject: [PATCH 17/41] Adds example content for admin budget new
---
app/assets/stylesheets/admin.scss | 5 +
app/controllers/admin/budgets_controller.rb | 3 +
app/views/admin/budgets/new.html.erb | 137 ++++++++++++++++++++
config/locales/admin.es.yml | 16 +++
4 files changed, 161 insertions(+)
create mode 100644 app/views/admin/budgets/new.html.erb
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
index cd8241fca..11a481c1e 100644
--- a/app/assets/stylesheets/admin.scss
+++ b/app/assets/stylesheets/admin.scss
@@ -36,6 +36,11 @@ body.admin {
input[type="text"], textarea {
width: 100%;
}
+
+ .input-group input[type="text"] {
+ border-radius: 0;
+ margin-bottom: 0 !important;
+ }
}
table {
diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
index a2f92a39e..7953aae75 100644
--- a/app/controllers/admin/budgets_controller.rb
+++ b/app/controllers/admin/budgets_controller.rb
@@ -6,4 +6,7 @@ class Admin::BudgetsController < Admin::BaseController
@budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page])
end
+ def new
+ end
+
end
diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb
new file mode 100644
index 000000000..66484f7b4
--- /dev/null
+++ b/app/views/admin/budgets/new.html.erb
@@ -0,0 +1,137 @@
+
+
+
<%= t("admin.budgets.new.title") %>
+
+
+
+
+
+
+
+
+
+
+
Nombre del budget
+
+ <%= link_to t("admin.budgets.new.add_group"), "#", class: "button float-right" %>
+
+
+ <%= t("admin.budgets.new.group") %>
+ ">
+
+
+
+
+
+
+
+
+
+
+
+
+ Nombre del grupo
+ <%= link_to t("admin.budgets.new.add_heading"), "#", class: "button float-right" %>
+
+
+
+ <%= t("admin.budgets.new.table_heading") %>
+ <%= t("admin.budgets.new.table_amount") %>
+ <%= t("admin.budgets.new.table_geozone") %>
+
+
+
+
+
+
+
+ <%= t("admin.budgets.new.no_heading") %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Heading 1 name
+
+
+ 9999€
+
+
+
+ <%= t("admin.budgets.new.table_geozone") %>
+
+
+
+
+
+ Heading 2 name
+
+
+ 24000000€
+
+
+
+ <%= t("admin.budgets.new.table_geozone") %>
+
+
+
+
+
+ Heading 3 name
+
+
+ 1265000€
+
+
+
+ <%= t("admin.budgets.new.table_geozone") %>
+
+
+
+
+
+
+
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index c5f0df247..0045eebfe 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -65,6 +65,22 @@ es:
filters:
open: Abiertos
finished: Terminados
+ new:
+ title: Nuevo presupuesto ciudadano
+ create: Crear presupuesto
+ name: Nombre del presupuesto
+ description: Descripción
+ phase: Fase
+ currency: Divisa
+ group: Nombre del grupo
+ add_group: Añadir nuevo grupo
+ heading: Nombre de la partida
+ add_heading: Añadir partida
+ save_heading: Guardar partida
+ no_heading: Este grupo no tiene ninguna partida asignada.
+ table_heading: Partida
+ table_amount: Cantidad
+ table_geozone: Ámbito de actuación
comments:
index:
filter: Filtro
From 3e892c6e7611dbb03d46331e38dda920f0e2897e Mon Sep 17 00:00:00 2001
From: Alberto Garcia Cabeza
Date: Thu, 28 Jul 2016 19:21:53 +0200
Subject: [PATCH 18/41] Adds translations and improve example content
---
app/assets/stylesheets/admin.scss | 4 ++
app/views/admin/budgets/new.html.erb | 62 +++++++++++++++-------------
config/locales/admin.en.yml | 22 +++++++++-
config/locales/admin.es.yml | 4 ++
4 files changed, 62 insertions(+), 30 deletions(-)
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
index 11a481c1e..196d0be17 100644
--- a/app/assets/stylesheets/admin.scss
+++ b/app/assets/stylesheets/admin.scss
@@ -47,6 +47,10 @@ body.admin {
th {
text-align: left;
+
+ &.with-button {
+ line-height: $line-height*2;
+ }
}
tr {
diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb
index 66484f7b4..f71e7c7a5 100644
--- a/app/views/admin/budgets/new.html.erb
+++ b/app/views/admin/budgets/new.html.erb
@@ -31,9 +31,6 @@
-
-
-
-
-
-
+
Nombre del grupo
<%= link_to t("admin.budgets.new.add_heading"), "#", class: "button float-right" %>
@@ -79,30 +81,37 @@
-
-
+
+
Heading 1 name
- 9999€
+ 190.000€
-
- <%= t("admin.budgets.new.table_geozone") %>
-
+ Geozone B
@@ -110,12 +119,10 @@
Heading 2 name
- 24000000€
+ 24.000.000€
-
- <%= t("admin.budgets.new.table_geozone") %>
-
+ Does not apply
@@ -123,14 +130,13 @@
Heading 3 name
- 1265000€
+ 1.265.000€
-
- <%= t("admin.budgets.new.table_geozone") %>
-
+ Geozone A
+
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index 7d32e3291..a778f6745 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -32,8 +32,6 @@ en:
editing: Edit banner
form:
submit_button: Save changes
- errors:
- form:
errors:
form:
error:
@@ -67,6 +65,26 @@ en:
filters:
open: Open
finished: Finished
+ new:
+ title: New participatory budget
+ create: Create budget
+ name: Budget's name
+ description: Description
+ phase: Phase
+ currency: Currency
+ group: Group's name
+ add_group: Add new group
+ create_group: Create group
+ heading: Heading's name
+ add_heading: Add heading
+ amount: Amount
+ save_heading: Save heading
+ no_heading: This group has no assigned heading.
+ geozone: Scope of operation
+ no_geozone: Does not apply
+ table_heading: Heading
+ table_amount: Amount
+ table_geozone: Scope of operation
comments:
index:
filter: Filter
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 0045eebfe..3154060bf 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -74,10 +74,14 @@ es:
currency: Divisa
group: Nombre del grupo
add_group: Añadir nuevo grupo
+ create_group: Crear grupo
heading: Nombre de la partida
add_heading: Añadir partida
+ amount: Cantidad
save_heading: Guardar partida
no_heading: Este grupo no tiene ninguna partida asignada.
+ geozone: Ámbito de actuación
+ no_geozone: No aplica
table_heading: Partida
table_amount: Cantidad
table_geozone: Ámbito de actuación
From 9014de269323581462be1aea4e61a822b559f033 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Fri, 29 Jul 2016 13:34:11 +0200
Subject: [PATCH 19/41] adds budgets_helper
---
app/helpers/budgets_helper.rb | 11 +++++++++++
app/models/budget.rb | 2 ++
2 files changed, 13 insertions(+)
create mode 100644 app/helpers/budgets_helper.rb
diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb
new file mode 100644
index 000000000..d281ef182
--- /dev/null
+++ b/app/helpers/budgets_helper.rb
@@ -0,0 +1,11 @@
+module BudgetsHelper
+
+ def budget_phases_select_options
+ Budget::VALID_PHASES.map { |ph| [ t("budget.phase.#{ph}"), ph ] }
+ end
+
+ def budget_currency_symbol_select_options
+ Budget::CURRENCY_SYMBOLS.map { |cs| [ cs, cs ] }
+ end
+
+end
\ No newline at end of file
diff --git a/app/models/budget.rb b/app/models/budget.rb
index d642e7d0c..18f30ba7c 100644
--- a/app/models/budget.rb
+++ b/app/models/budget.rb
@@ -1,7 +1,9 @@
class Budget < ActiveRecord::Base
VALID_PHASES = %W{on_hold accepting selecting balloting finished}
+ CURRENCY_SYMBOLS = %W{€ $ £ ¥}
+ validates :name, presence: true
validates :phase, inclusion: { in: VALID_PHASES }
has_many :investments, dependent: :destroy
From 6fce9df4513817b45163e8dbab1ff1a32d7b47ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Fri, 29 Jul 2016 13:34:41 +0200
Subject: [PATCH 20/41] adds admin creation of budgets
---
app/controllers/admin/budgets_controller.rb | 16 +++
app/views/admin/budgets/new.html.erb | 145 +++-----------------
config/locales/admin.en.yml | 2 +
config/locales/admin.es.yml | 2 +
config/locales/es.yml | 2 +-
spec/features/admin/budgets_spec.rb | 35 ++++-
6 files changed, 67 insertions(+), 135 deletions(-)
diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
index 7953aae75..d6f2789e6 100644
--- a/app/controllers/admin/budgets_controller.rb
+++ b/app/controllers/admin/budgets_controller.rb
@@ -7,6 +7,22 @@ class Admin::BudgetsController < Admin::BaseController
end
def new
+ @budget = Budget.new
end
+ def create
+ @budget = Budget.new(budget_params)
+ if @budget.save
+ redirect_to admin_budgets_path, notice: t('admin.budgets.create.notice')
+ else
+ render :new
+ end
+ end
+
+ private
+
+ def budget_params
+ params.require(:budget).permit(:name, :description, :phase, :currency_symbol)
+ end
+
end
diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb
index f71e7c7a5..c7985b98f 100644
--- a/app/views/admin/budgets/new.html.erb
+++ b/app/views/admin/budgets/new.html.erb
@@ -2,142 +2,29 @@
<%= t("admin.budgets.new.title") %>
-
- <%= t("admin.budgets.new.name") %>
- ">
- <%= t("admin.budgets.new.description") %>
- ">
+ <%= form_for [:admin, @budget] do |f| %>
+
+ <%= f.label :name, t("admin.budgets.new.name") %>
+ <%= f.text_field :name,
+ label: false,
+ maxlength: 30,
+ placeholder: t("admin.budgets.new.name") %>
+
+ <%= f.label :description, t("admin.budgets.new.description") %>
+ <%= f.text_area :description, rows: 3, maxlength: 6000, label: false, placeholder: t("admin.budgets.new.description") %>
+
-
- <%= t("admin.budgets.new.phase") %>
- Seleccionando
- Votación final
- Terminado
-
+ <%= f.label :description, t("admin.budgets.new.phase") %>
+ <%= f.select :phase, budget_phases_select_options, {label: false} %>
-
- <%= t("admin.budgets.new.currency") %>
- €
- $
- £
- ¥
-
+ <%= f.label :description, t("admin.budgets.new.currency") %>
+ <%= f.select :currency_symbol, budget_currency_symbol_select_options, {label: false} %>
" class="button success">
-
+ <% end %>
-
-
-
Nombre del budget
-
- <%= link_to t("admin.budgets.new.add_group"), "#", class: "button float-right" %>
-
-
-
-
-
-
-
-
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index a778f6745..d55d24726 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -65,6 +65,8 @@ en:
filters:
open: Open
finished: Finished
+ create:
+ notice: New participatory budget created successfully!
new:
title: New participatory budget
create: Create budget
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 3154060bf..8ed57d4d8 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -65,6 +65,8 @@ es:
filters:
open: Abiertos
finished: Terminados
+ create:
+ notice: ¡Nueva campaña de presupuestos participativos creada con éxito!
new:
title: Nuevo presupuesto ciudadano
create: Crear presupuesto
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 282340395..195a80766 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -35,7 +35,7 @@ es:
menu: Menú
budget:
phase:
- on_hold: Pausa
+ on_hold: En pausa
accepting: Aceptando propuestas
selecting: Fase de selección
balloting: Fase de Votación
diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb
index 8326a5dac..c684d8a55 100644
--- a/spec/features/admin/budgets_spec.rb
+++ b/spec/features/admin/budgets_spec.rb
@@ -7,7 +7,7 @@ feature 'Admin budgets' do
login_as(admin.user)
end
- context "Feature flag" do
+ context 'Feature flag' do
xscenario 'Disabled with a feature flag' do
Setting['feature.budgets'] = nil
@@ -16,7 +16,7 @@ feature 'Admin budgets' do
end
- context "Index" do
+ context 'Index' do
scenario 'Displaying budgets' do
budget = create(:budget)
@@ -40,14 +40,14 @@ feature 'Admin budgets' do
expect(page).to have_content(budget4.name)
expect(page).to_not have_content(budget5.name)
- click_link "Finished"
+ click_link 'Finished'
expect(page).to_not have_content(budget1.name)
expect(page).to_not have_content(budget2.name)
expect(page).to_not have_content(budget3.name)
expect(page).to_not have_content(budget4.name)
expect(page).to have_content(budget5.name)
- click_link "Open"
+ click_link 'Open'
expect(page).to have_content(budget1.name)
expect(page).to have_content(budget2.name)
expect(page).to have_content(budget3.name)
@@ -56,7 +56,7 @@ feature 'Admin budgets' do
end
- scenario "Current filter is properly highlighted" do
+ scenario 'Current filter is properly highlighted' do
filters_links = {'open' => 'Open', 'finished' => 'Finished'}
visit admin_budgets_path
@@ -76,4 +76,29 @@ feature 'Admin budgets' do
end
end
+
+ context 'New' do
+ scenario 'Create budget' do
+ visit admin_budgets_path
+ click_link 'Create new'
+
+ fill_in 'budget_name', with: 'M30 - Summer campaign'
+ fill_in 'budget_description', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30'
+ select 'Accepting proposals', from: 'budget[phase]'
+
+ click_button 'Create budget'
+
+ expect(page).to have_content 'New participatory budget created successfully!'
+ expect(page).to have_content 'M30 - Summer campaign'
+ end
+
+ scenario 'Name is mandatory' do
+ visit new_admin_budget_path
+ click_button 'Create budget'
+
+ expect(page).to_not have_content 'New participatory budget created successfully!'
+ expect(page).to have_css("label.error", text: "Budget's name")
+ end
+
+ end
end
\ No newline at end of file
From 49bc6533e8e2e2c13c8c1487dbc05031ee41ef8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Fri, 29 Jul 2016 13:39:08 +0200
Subject: [PATCH 21/41] adds explicit permission to admin to read budgets
---
app/controllers/admin/budgets_controller.rb | 2 ++
app/models/abilities/administrator.rb | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
index d6f2789e6..02894240e 100644
--- a/app/controllers/admin/budgets_controller.rb
+++ b/app/controllers/admin/budgets_controller.rb
@@ -2,6 +2,8 @@ class Admin::BudgetsController < Admin::BaseController
has_filters %w{open finished}, only: :index
+ load_and_authorize_resource
+
def index
@budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page])
end
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 42e4ecbd3..65f97db2e 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -42,7 +42,7 @@ module Abilities
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
- can [:create, :update], Budget
+ can [:read, :create, :update], Budget
can [:hide, :update], Budget::Investment
can :valuate, Budget::Investment, budget: { valuating: true }
can :create, Budget::ValuatorAssignment
From 724ccf175c1a23a1e882c363f7d6fa54a565e1d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Fri, 29 Jul 2016 14:52:37 +0200
Subject: [PATCH 22/41] adds budget show to admin
---
app/controllers/admin/budgets_controller.rb | 5 ++++-
app/views/admin/budgets/new.html.erb | 3 +--
app/views/admin/budgets/show.html.erb | 12 ++++++++++++
config/locales/admin.en.yml | 3 +++
config/locales/admin.es.yml | 3 +++
spec/features/admin/budgets_spec.rb | 2 +-
6 files changed, 24 insertions(+), 4 deletions(-)
create mode 100644 app/views/admin/budgets/show.html.erb
diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
index 02894240e..2e8a28fe6 100644
--- a/app/controllers/admin/budgets_controller.rb
+++ b/app/controllers/admin/budgets_controller.rb
@@ -8,6 +8,9 @@ class Admin::BudgetsController < Admin::BaseController
@budgets = Budget.send(@current_filter).order(created_at: :desc).page(params[:page])
end
+ def show
+ end
+
def new
@budget = Budget.new
end
@@ -15,7 +18,7 @@ class Admin::BudgetsController < Admin::BaseController
def create
@budget = Budget.new(budget_params)
if @budget.save
- redirect_to admin_budgets_path, notice: t('admin.budgets.create.notice')
+ redirect_to admin_budget_path(@budget), notice: t('admin.budgets.create.notice')
else
render :new
end
diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb
index c7985b98f..019ca460f 100644
--- a/app/views/admin/budgets/new.html.erb
+++ b/app/views/admin/budgets/new.html.erb
@@ -26,5 +26,4 @@
" class="button success">
<% end %>
-
-
+
\ No newline at end of file
diff --git a/app/views/admin/budgets/show.html.erb b/app/views/admin/budgets/show.html.erb
new file mode 100644
index 000000000..20185b2ba
--- /dev/null
+++ b/app/views/admin/budgets/show.html.erb
@@ -0,0 +1,12 @@
+
+
+
<%= @budget.name %>
+
+ <%= simple_format(text_with_links(@budget.description), {}, sanitize: false) %>
+
+
+ <%= t('admin.budgets.show.phase') %>: <%= t("budget.phase.#{@budget.phase}") %> |
+ <%= t('admin.budgets.show.currency') %>: <%= @budget.currency_symbol %>
+
+
+
\ No newline at end of file
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index d55d24726..812e1a45c 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -87,6 +87,9 @@ en:
table_heading: Heading
table_amount: Amount
table_geozone: Scope of operation
+ show:
+ phase: Current phase
+ currency: Currency
comments:
index:
filter: Filter
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 8ed57d4d8..1afc01ef2 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -87,6 +87,9 @@ es:
table_heading: Partida
table_amount: Cantidad
table_geozone: Ámbito de actuación
+ show:
+ phase: Fase actual
+ currency: Divisa
comments:
index:
filter: Filtro
diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb
index c684d8a55..f38d2c9f5 100644
--- a/spec/features/admin/budgets_spec.rb
+++ b/spec/features/admin/budgets_spec.rb
@@ -55,7 +55,6 @@ feature 'Admin budgets' do
expect(page).to_not have_content(budget5.name)
end
-
scenario 'Current filter is properly highlighted' do
filters_links = {'open' => 'Open', 'finished' => 'Finished'}
@@ -78,6 +77,7 @@ feature 'Admin budgets' do
end
context 'New' do
+
scenario 'Create budget' do
visit admin_budgets_path
click_link 'Create new'
From 9abf6e155888148752707eb7c7eb320ece4c1337 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Fri, 29 Jul 2016 15:13:28 +0200
Subject: [PATCH 23/41] updates dependencies bullet, coveralls, faker, uglifier
---
Gemfile.lock | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Gemfile.lock b/Gemfile.lock
index 5ccd7f8ba..5f35de786 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -67,7 +67,7 @@ GEM
bcrypt (3.1.11)
browser (2.2.0)
builder (3.2.2)
- bullet (5.1.1)
+ bullet (5.2.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.10.0)
byebug (9.0.5)
@@ -114,12 +114,12 @@ GEM
execjs
coffee-script-source (1.10.0)
concurrent-ruby (1.0.2)
- coveralls (0.8.14)
+ coveralls (0.8.15)
json (>= 1.8, < 3)
simplecov (~> 0.12.0)
term-ansicolor (~> 1.3)
thor (~> 0.19.1)
- tins (~> 1.6.0)
+ tins (>= 1.6.0, < 2)
daemons (1.2.3)
dalli (2.7.6)
database_cleaner (1.5.3)
@@ -156,7 +156,7 @@ GEM
factory_girl_rails (4.7.0)
factory_girl (~> 4.7.0)
railties (>= 3.0.0)
- faker (1.6.5)
+ faker (1.6.6)
i18n (~> 0.5)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
@@ -396,7 +396,7 @@ GEM
thread (0.2.2)
thread_safe (0.3.5)
tilt (2.0.5)
- tins (1.6.0)
+ tins (1.11.0)
tolk (1.9.3)
rails (>= 4.0, < 4.3)
safe_yaml (>= 0.8.6)
@@ -408,7 +408,7 @@ GEM
tilt (>= 1.4, < 3)
tzinfo (1.2.2)
thread_safe (~> 0.1)
- uglifier (3.0.0)
+ uglifier (3.0.1)
execjs (>= 0.3.0, < 3)
unicorn (5.1.0)
kgio (~> 2.6)
From c4768e380d01efbbac3d63a52f86fb49861b2abc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Sat, 30 Jul 2016 09:56:13 +0200
Subject: [PATCH 24/41] saves querys
---
app/views/shared/_admin_login_items.html.erb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb
index 6ba10bbca..013320f38 100644
--- a/app/views/shared/_admin_login_items.html.erb
+++ b/app/views/shared/_admin_login_items.html.erb
@@ -5,13 +5,13 @@
<% end %>
- <% if current_user.moderator? || current_user.administrator? %>
+ <% if current_user.administrator? || current_user.moderator? %>
<%= link_to t("layouts.header.moderation"), moderation_root_path %>
<% end %>
- <% if feature?(:spending_proposals) && (current_user.valuator? || current_user.administrator?) %>
+ <% if feature?(:spending_proposals) && (current_user.administrator? || current_user.valuator?) %>
<%= link_to t("layouts.header.valuation"), valuation_root_path %>
From 99b9c3867ed80fb8ba60300e5b09867bd52d923f Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Fri, 29 Jul 2016 18:01:44 +0200
Subject: [PATCH 25/41] adds pending spec
---
spec/features/emails_spec.rb | 3 +++
1 file changed, 3 insertions(+)
diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb
index 429d74738..94c70df4f 100644
--- a/spec/features/emails_spec.rb
+++ b/spec/features/emails_spec.rb
@@ -229,6 +229,9 @@ feature 'Emails' do
expect(email).to have_body_text(/#{account_path}/)
end
+ xscenario "Delete all Notifications included in the digest after email sent" do
+ end
+
end
context "User invites" do
From 9d9bf488fccae054ce7c49c307861628a5c140d0 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Tue, 2 Aug 2016 20:35:33 +0200
Subject: [PATCH 26/41] does not create notifications for blocked or erased
users
---
app/models/proposal.rb | 2 +-
app/models/user.rb | 1 +
spec/features/proposal_notifications_spec.rb | 38 +++++++++++++++++
spec/models/proposal_spec.rb | 44 ++++++++++++++++++++
spec/models/user_spec.rb | 28 +++++++++++++
5 files changed, 112 insertions(+), 1 deletion(-)
diff --git a/app/models/proposal.rb b/app/models/proposal.rb
index 7d2bddb30..9a92a8d18 100644
--- a/app/models/proposal.rb
+++ b/app/models/proposal.rb
@@ -99,7 +99,7 @@ class Proposal < ActiveRecord::Base
end
def voters
- votes_for.voters
+ User.active.where(id: votes_for.voters)
end
def editable?
diff --git a/app/models/user.rb b/app/models/user.rb
index 4bb09c4a0..60bc2364a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -53,6 +53,7 @@ class User < ActiveRecord::Base
scope :for_render, -> { includes(:organization) }
scope :by_document, -> (document_type, document_number) { where(document_type: document_type, document_number: document_number) }
scope :email_digest, -> { where(email_digest: true) }
+ scope :active, -> { where(erased_at: nil) }
before_validation :clean_document_number
diff --git a/spec/features/proposal_notifications_spec.rb b/spec/features/proposal_notifications_spec.rb
index 6092289f0..a10e41a7d 100644
--- a/spec/features/proposal_notifications_spec.rb
+++ b/spec/features/proposal_notifications_spec.rb
@@ -24,6 +24,44 @@ feature 'Proposal Notifications' do
expect(page).to have_content "Please share it with others so we can make it happen!"
end
+ scenario "Send a notification (Active voter)" do
+ author = create(:user)
+ proposal = create(:proposal, author: author)
+
+ voter = create(:user, :level_two)
+ create(:vote, voter: voter, votable: proposal)
+
+ create_proposal_notification(proposal)
+
+ expect(Notification.count).to eq(1)
+ end
+
+ scenario "Send a notification (Blocked voter)" do
+ author = create(:user)
+ proposal = create(:proposal, author: author)
+
+ voter = create(:user, :level_two)
+ create(:vote, voter: voter, votable: proposal)
+ voter.block
+
+ create_proposal_notification(proposal)
+
+ expect(Notification.count).to eq(0)
+ end
+
+ scenario "Send a notification (Erased voter)" do
+ author = create(:user)
+ proposal = create(:proposal, author: author)
+
+ voter = create(:user, :level_two)
+ create(:vote, voter: voter, votable: proposal)
+ voter.erase
+
+ create_proposal_notification(proposal)
+
+ expect(Notification.count).to eq(0)
+ end
+
scenario "Show notifications" do
proposal = create(:proposal)
notification1 = create(:proposal_notification, proposal: proposal, title: "Hey guys", body: "Just wanted to let you know that...")
diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb
index 4958204ec..247cd9e66 100644
--- a/spec/models/proposal_spec.rb
+++ b/spec/models/proposal_spec.rb
@@ -367,6 +367,50 @@ describe Proposal do
end
end
+ describe "voters" do
+
+ it "returns users that have voted for the proposal" do
+ proposal = create(:proposal)
+ voter1 = create(:user, :level_two)
+ voter2 = create(:user, :level_two)
+ voter3 = create(:user, :level_two)
+
+ create(:vote, voter: voter1, votable: proposal)
+ create(:vote, voter: voter2, votable: proposal)
+
+ expect(proposal.voters).to include(voter1)
+ expect(proposal.voters).to include(voter2)
+ expect(proposal.voters).to_not include(voter3)
+ end
+
+ it "does not return users that have been erased" do
+ proposal = create(:proposal)
+ voter1 = create(:user, :level_two)
+ voter2 = create(:user, :level_two)
+
+ create(:vote, voter: voter1, votable: proposal)
+ create(:vote, voter: voter2, votable: proposal)
+ voter2.erase
+
+ expect(proposal.voters).to include(voter1)
+ expect(proposal.voters).to_not include(voter2)
+ end
+
+ it "does not return users that have been blocked" do
+ proposal = create(:proposal)
+ voter1 = create(:user, :level_two)
+ voter2 = create(:user, :level_two)
+
+ create(:vote, voter: voter1, votable: proposal)
+ create(:vote, voter: voter2, votable: proposal)
+ voter2.block
+
+ expect(proposal.voters).to include(voter1)
+ expect(proposal.voters).to_not include(voter2)
+ end
+
+ end
+
describe "search" do
context "attributes" do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index d54f3a42e..b6084a971 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -325,6 +325,34 @@ describe User do
end
+ describe "scopes" do
+
+ describe "active" do
+
+ it "returns users that have not been erased" do
+ user1 = create(:user, erased_at: nil)
+ user2 = create(:user, erased_at: nil)
+ user3 = create(:user, erased_at: Time.now)
+
+ expect(User.active).to include(user1)
+ expect(User.active).to include(user2)
+ expect(User.active).to_not include(user3)
+ end
+
+ it "returns users that have not been blocked" do
+ user1 = create(:user)
+ user2 = create(:user)
+ user3 = create(:user)
+ user3.block
+
+ expect(User.active).to include(user1)
+ expect(User.active).to include(user2)
+ expect(User.active).to_not include(user3)
+ end
+
+ end
+ end
+
describe "self.search" do
it "find users by email" do
user1 = create(:user, email: "larry@consul.dev")
From 6281af2a7d9aa490c5cd2af64a54c1402ce1d946 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 19:33:23 +0200
Subject: [PATCH 27/41] adds emailed_at attribute to notifications
---
.../20160803154011_add_emailed_at_to_notifications.rb | 5 +++++
db/schema.rb | 11 ++++++-----
2 files changed, 11 insertions(+), 5 deletions(-)
create mode 100644 db/migrate/20160803154011_add_emailed_at_to_notifications.rb
diff --git a/db/migrate/20160803154011_add_emailed_at_to_notifications.rb b/db/migrate/20160803154011_add_emailed_at_to_notifications.rb
new file mode 100644
index 000000000..83e38b00f
--- /dev/null
+++ b/db/migrate/20160803154011_add_emailed_at_to_notifications.rb
@@ -0,0 +1,5 @@
+class AddEmailedAtToNotifications < ActiveRecord::Migration
+ def change
+ add_column :notifications, :emailed_at, :datetime
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 6932611e4..becde4f8a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160617172616) do
+ActiveRecord::Schema.define(version: 20160803154011) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -251,10 +251,11 @@ ActiveRecord::Schema.define(version: 20160617172616) do
add_index "moderators", ["user_id"], name: "index_moderators_on_user_id", using: :btree
create_table "notifications", force: :cascade do |t|
- t.integer "user_id"
- t.integer "notifiable_id"
- t.string "notifiable_type"
- t.integer "counter", default: 1
+ t.integer "user_id"
+ t.integer "notifiable_id"
+ t.string "notifiable_type"
+ t.integer "counter", default: 1
+ t.datetime "emailed_at"
end
add_index "notifications", ["user_id"], name: "index_notifications_on_user_id", using: :btree
From b087fe8fb78598cea3df6424d49f117b9eab5d95 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 19:33:37 +0200
Subject: [PATCH 28/41] refactors email digest
---
app/mailers/mailer.rb | 4 ++--
app/models/notification.rb | 8 +++++---
lib/email_digest.rb | 21 +++++++++++++++------
lib/tasks/emails.rake | 6 ++++--
4 files changed, 26 insertions(+), 13 deletions(-)
diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb
index ad87359af..25c019857 100644
--- a/app/mailers/mailer.rb
+++ b/app/mailers/mailer.rb
@@ -60,8 +60,8 @@ class Mailer < ApplicationMailer
end
end
- def proposal_notification_digest(user)
- @notifications = user.notifications.where(notifiable_type: "ProposalNotification")
+ def proposal_notification_digest(user, notifications)
+ @notifications = notifications
with_user(user) do
mail(to: user.email, subject: t('mailers.proposal_notification_digest.title', org_name: Setting['org_name']))
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 9695c1b01..c6c32eb8d 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -2,9 +2,11 @@ class Notification < ActiveRecord::Base
belongs_to :user, counter_cache: true
belongs_to :notifiable, polymorphic: true
- scope :unread, -> { all }
- scope :recent, -> { order(id: :desc) }
- scope :for_render, -> { includes(:notifiable) }
+ scope :unread, -> { all }
+ scope :recent, -> { order(id: :desc) }
+ scope :not_emailed, -> { where(emailed_at: nil) }
+ scope :for_render, -> { includes(:notifiable) }
+
def timestamp
notifiable.created_at
diff --git a/lib/email_digest.rb b/lib/email_digest.rb
index 90838f78f..0b4d796db 100644
--- a/lib/email_digest.rb
+++ b/lib/email_digest.rb
@@ -1,13 +1,22 @@
class EmailDigest
- def initialize
+ attr_accessor :user, :notifications
+
+ def initialize(user)
+ @user = user
end
- def create
- User.email_digest.each do |user|
- if user.notifications.where(notifiable_type: "ProposalNotification").any?
- Mailer.proposal_notification_digest(user).deliver_later
- end
+ def notifications
+ user.notifications.not_emailed.where(notifiable_type: "ProposalNotification").to_a
+ end
+
+ def pending_notifications?
+ notifications.any?
+ end
+
+ def deliver
+ if pending_notifications?
+ Mailer.proposal_notification_digest(user, notifications).deliver_later
end
end
diff --git a/lib/tasks/emails.rake b/lib/tasks/emails.rake
index 6670264a5..7c76b20c8 100644
--- a/lib/tasks/emails.rake
+++ b/lib/tasks/emails.rake
@@ -2,8 +2,10 @@ namespace :emails do
desc "Sends email digest of proposal notifications to each user"
task digest: :environment do
- email_digest = EmailDigest.new
- email_digest.create
+ User.email_digest.find_each do |user|
+ email_digest = EmailDigest.new(user)
+ email_digest.deliver
+ end
end
end
From 0faff2f01c2c62e9d75e4ded293428c0f8c26f75 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 19:33:43 +0200
Subject: [PATCH 29/41] adds specs
---
spec/lib/email_digests_spec.rb | 92 +++++++++++++++++++++++++++++++++-
1 file changed, 90 insertions(+), 2 deletions(-)
diff --git a/spec/lib/email_digests_spec.rb b/spec/lib/email_digests_spec.rb
index 6fc6eef53..244d1270a 100644
--- a/spec/lib/email_digests_spec.rb
+++ b/spec/lib/email_digests_spec.rb
@@ -2,8 +2,96 @@ require 'rails_helper'
describe EmailDigest do
- describe "create" do
- pending "only send unread notifications"
+ describe "notifications" do
+
+ it "returns notifications for a user" do
+ user1 = create(:user)
+ user2 = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ notification1 = create(:notification, notifiable: proposal_notification, user: user1)
+ notification2 = create(:notification, notifiable: proposal_notification, user: user2)
+
+ email_digest = EmailDigest.new(user1)
+
+ expect(email_digest.notifications).to include(notification1)
+ expect(email_digest.notifications).to_not include(notification2)
+ end
+
+ it "returns only proposal notifications" do
+ user = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ comment = create(:comment)
+
+ notification1 = create(:notification, notifiable: proposal_notification, user: user)
+ notification2 = create(:notification, notifiable: comment, user: user)
+
+ email_digest = EmailDigest.new(user)
+
+ expect(email_digest.notifications).to include(notification1)
+ expect(email_digest.notifications).to_not include(notification2)
+ end
+
+ end
+
+ describe "pending_notifications?" do
+
+ it "returns true when notifications have not been emailed" do
+ user = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ notification = create(:notification, notifiable: proposal_notification, user: user)
+
+ email_digest = EmailDigest.new(user)
+ expect(email_digest.pending_notifications?).to be
+ end
+
+ it "returns false when notifications have been emailed" do
+ user = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ notification = create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
+
+ email_digest = EmailDigest.new(user)
+ expect(email_digest.pending_notifications?).to_not be
+ end
+
+ it "returns false when there are no notifications for a user" do
+ user = create(:user)
+ email_digest = EmailDigest.new(user)
+ expect(email_digest.pending_notifications?).to_not be
+ end
+
+ end
+
+ describe "deliver" do
+
+ it "delivers email if notifications pending" do
+ user = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ notification = create(:notification, notifiable: proposal_notification, user: user)
+
+ email_digest = EmailDigest.new(user)
+ email_digest.deliver
+
+ email = open_last_email
+ expect(email).to have_subject("Proposal notifications in Consul")
+ end
+
+ it "does not deliver email if no notifications pending" do
+ user = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ notification = create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
+
+ email_digest = EmailDigest.new(user)
+ email_digest.deliver
+
+ expect(all_emails.count).to eq(0)
+ end
+
end
end
\ No newline at end of file
From 63274dfe08f8ebe259fce31382f4fb77890d9de0 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 19:48:43 +0200
Subject: [PATCH 30/41] marks notifications as emailed after rake
---
lib/email_digest.rb | 8 ++++++--
lib/tasks/emails.rake | 1 +
spec/lib/email_digests_spec.rb | 23 +++++++++++++++++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/lib/email_digest.rb b/lib/email_digest.rb
index 0b4d796db..209014dcc 100644
--- a/lib/email_digest.rb
+++ b/lib/email_digest.rb
@@ -7,7 +7,7 @@ class EmailDigest
end
def notifications
- user.notifications.not_emailed.where(notifiable_type: "ProposalNotification").to_a
+ user.notifications.not_emailed.where(notifiable_type: "ProposalNotification")
end
def pending_notifications?
@@ -16,8 +16,12 @@ class EmailDigest
def deliver
if pending_notifications?
- Mailer.proposal_notification_digest(user, notifications).deliver_later
+ Mailer.proposal_notification_digest(user, notifications.to_a).deliver_later
end
end
+ def mark_as_emailed
+ notifications.update_all(emailed_at: Time.now)
+ end
+
end
\ No newline at end of file
diff --git a/lib/tasks/emails.rake b/lib/tasks/emails.rake
index 7c76b20c8..ffadebf05 100644
--- a/lib/tasks/emails.rake
+++ b/lib/tasks/emails.rake
@@ -5,6 +5,7 @@ namespace :emails do
User.email_digest.find_each do |user|
email_digest = EmailDigest.new(user)
email_digest.deliver
+ email_digest.mark_as_emailed
end
end
diff --git a/spec/lib/email_digests_spec.rb b/spec/lib/email_digests_spec.rb
index 244d1270a..d03ea91fd 100644
--- a/spec/lib/email_digests_spec.rb
+++ b/spec/lib/email_digests_spec.rb
@@ -94,4 +94,27 @@ describe EmailDigest do
end
+ describe "mark_as_emailed" do
+
+ it "marks notifications as emailed" do
+ user = create(:user)
+
+ proposal_notification = create(:proposal_notification)
+ notification1 = create(:notification, notifiable: proposal_notification, user: user)
+ notification2 = create(:notification, notifiable: proposal_notification, user: user)
+
+ expect(notification1.emailed_at).to_not be
+ expect(notification2.emailed_at).to_not be
+
+ email_digest = EmailDigest.new(user)
+ email_digest.mark_as_emailed
+
+ notification1.reload
+ notification2.reload
+ expect(notification1.emailed_at).to be
+ expect(notification2.emailed_at).to be
+ end
+
+ end
+
end
\ No newline at end of file
From 5bd7fdb26369f59410dc71204af7069e74cd6925 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 20:05:08 +0200
Subject: [PATCH 31/41] fixes specs
---
spec/features/emails_spec.rb | 11 +++++++----
spec/lib/email_digests_spec.rb | 15 +++++++++++----
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb
index 94c70df4f..a9569e9b2 100644
--- a/spec/features/emails_spec.rb
+++ b/spec/features/emails_spec.rb
@@ -201,8 +201,9 @@ feature 'Emails' do
notification2 = create_proposal_notification(proposal2)
notification3 = create_proposal_notification(proposal3)
- email_digest = EmailDigest.new
- email_digest.create
+ email_digest = EmailDigest.new(user)
+ email_digest.deliver
+ email_digest.mark_as_emailed
email = open_last_email
expect(email).to have_subject("Proposal notifications in Consul")
@@ -227,9 +228,11 @@ feature 'Emails' do
expect(email).to_not have_body_text(proposal3.title)
expect(email).to have_body_text(/#{account_path}/)
- end
- xscenario "Delete all Notifications included in the digest after email sent" do
+ notification1.reload
+ notification2.reload
+ expect(notification1.emailed_at).to be
+ expect(notification2.emailed_at).to be
end
end
diff --git a/spec/lib/email_digests_spec.rb b/spec/lib/email_digests_spec.rb
index d03ea91fd..ae2122793 100644
--- a/spec/lib/email_digests_spec.rb
+++ b/spec/lib/email_digests_spec.rb
@@ -73,6 +73,7 @@ describe EmailDigest do
proposal_notification = create(:proposal_notification)
notification = create(:notification, notifiable: proposal_notification, user: user)
+ reset_mailer
email_digest = EmailDigest.new(user)
email_digest.deliver
@@ -86,6 +87,7 @@ describe EmailDigest do
proposal_notification = create(:proposal_notification)
notification = create(:notification, notifiable: proposal_notification, user: user, emailed_at: Time.now)
+ reset_mailer
email_digest = EmailDigest.new(user)
email_digest.deliver
@@ -97,22 +99,27 @@ describe EmailDigest do
describe "mark_as_emailed" do
it "marks notifications as emailed" do
- user = create(:user)
+ user1 = create(:user)
+ user2 = create(:user)
proposal_notification = create(:proposal_notification)
- notification1 = create(:notification, notifiable: proposal_notification, user: user)
- notification2 = create(:notification, notifiable: proposal_notification, user: user)
+ notification1 = create(:notification, notifiable: proposal_notification, user: user1)
+ notification2 = create(:notification, notifiable: proposal_notification, user: user1)
+ notification3 = create(:notification, notifiable: proposal_notification, user: user2)
expect(notification1.emailed_at).to_not be
expect(notification2.emailed_at).to_not be
+ expect(notification3.emailed_at).to_not be
- email_digest = EmailDigest.new(user)
+ email_digest = EmailDigest.new(user1)
email_digest.mark_as_emailed
notification1.reload
notification2.reload
+ notification3.reload
expect(notification1.emailed_at).to be
expect(notification2.emailed_at).to be
+ expect(notification3.emailed_at).to_not be
end
end
From 64a614c67f2ce55e815980df5bd989879945e131 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Wed, 3 Aug 2016 20:20:52 +0200
Subject: [PATCH 32/41] adds geozone helper to map ids and names
---
app/helpers/geozones_helper.rb | 5 +++++
spec/helpers/geozones_helper_spec.rb | 15 +++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/app/helpers/geozones_helper.rb b/app/helpers/geozones_helper.rb
index bfc5f9105..ce03e0579 100644
--- a/app/helpers/geozones_helper.rb
+++ b/app/helpers/geozones_helper.rb
@@ -8,4 +8,9 @@ module GeozonesHelper
Geozone.all.order(name: :asc).collect { |g| [ g.name, g.id ] }
end
+ def geozone_name_from_id(g_id)
+ @all_geozones ||= Geozone.all.collect{ |g| [ g.id, g.name ] }.to_h
+ @all_geozones[g_id] || t("geozones.none")
+ end
+
end
diff --git a/spec/helpers/geozones_helper_spec.rb b/spec/helpers/geozones_helper_spec.rb
index 605a774a6..0c0c13d70 100644
--- a/spec/helpers/geozones_helper_spec.rb
+++ b/spec/helpers/geozones_helper_spec.rb
@@ -31,4 +31,19 @@ describe GeozonesHelper do
end
end
+ describe "#geozone_name_from_id" do
+
+ it "returns geozone name if present" do
+ g1 = create(:geozone, name: "AAA")
+ g2 = create(:geozone, name: "BBB")
+
+ expect(geozone_name_from_id(g1.id)).to eq "AAA"
+ expect(geozone_name_from_id(g2.id)).to eq "BBB"
+ end
+
+ it "returns default string for no geozone if geozone is blank" do
+ expect(geozone_name_from_id(nil)).to eq "All city"
+ end
+ end
+
end
From 0f7e23bec49a2494dce28c771a0b521ea549111e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Wed, 3 Aug 2016 20:23:41 +0200
Subject: [PATCH 33/41] adds budget's groups & headings to admin
---
.../admin/budget_groups_controller.rb | 15 ++++
.../admin/budget_headings_controller.rb | 16 ++++
app/controllers/admin/budgets_controller.rb | 1 +
app/models/abilities/administrator.rb | 4 +-
app/views/admin/budget_groups/create.js.erb | 2 +
app/views/admin/budget_headings/create.js.erb | 2 +
app/views/admin/budgets/_group.html.erb | 76 +++++++++++++++++++
app/views/admin/budgets/_groups.html.erb | 34 +++++++++
app/views/admin/budgets/new.html.erb | 2 +-
app/views/admin/budgets/show.html.erb | 4 +
config/locales/admin.en.yml | 9 ++-
config/locales/admin.es.yml | 9 ++-
spec/features/admin/budgets_spec.rb | 54 +++++++++++++
13 files changed, 220 insertions(+), 8 deletions(-)
create mode 100644 app/controllers/admin/budget_groups_controller.rb
create mode 100644 app/controllers/admin/budget_headings_controller.rb
create mode 100644 app/views/admin/budget_groups/create.js.erb
create mode 100644 app/views/admin/budget_headings/create.js.erb
create mode 100644 app/views/admin/budgets/_group.html.erb
create mode 100644 app/views/admin/budgets/_groups.html.erb
diff --git a/app/controllers/admin/budget_groups_controller.rb b/app/controllers/admin/budget_groups_controller.rb
new file mode 100644
index 000000000..18f5a6b12
--- /dev/null
+++ b/app/controllers/admin/budget_groups_controller.rb
@@ -0,0 +1,15 @@
+class Admin::BudgetGroupsController < Admin::BaseController
+
+ def create
+ @budget = Budget.find params[:budget_id]
+ @budget.groups.create(budget_group_params)
+ @groups = @budget.groups.includes(:headings)
+ end
+
+ private
+
+ def budget_group_params
+ params.require(:budget_group).permit(:name)
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb
new file mode 100644
index 000000000..3c8ccafa0
--- /dev/null
+++ b/app/controllers/admin/budget_headings_controller.rb
@@ -0,0 +1,16 @@
+class Admin::BudgetHeadingsController < Admin::BaseController
+
+ def create
+ @budget = Budget.find params[:budget_id]
+ @budget_group = @budget.groups.find params[:budget_group_id]
+ @budget_group.headings.create(budget_heading_params)
+ @headings = @budget_group.headings
+ end
+
+ private
+
+ def budget_heading_params
+ params.require(:budget_heading).permit(:name, :price, :geozone_id)
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admin/budgets_controller.rb b/app/controllers/admin/budgets_controller.rb
index 2e8a28fe6..144b43a7f 100644
--- a/app/controllers/admin/budgets_controller.rb
+++ b/app/controllers/admin/budgets_controller.rb
@@ -9,6 +9,7 @@ class Admin::BudgetsController < Admin::BaseController
end
def show
+ @budget = Budget.includes(groups: :headings).find(params[:id])
end
def new
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 65f97db2e..f3f0b8f9b 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -42,7 +42,9 @@ module Abilities
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
- can [:read, :create, :update], Budget
+ can [:index, :read, :new, :create, :update, :destroy], Budget
+ can [:read, :create, :update, :destroy], Budget::Group
+ can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :update], Budget::Investment
can :valuate, Budget::Investment, budget: { valuating: true }
can :create, Budget::ValuatorAssignment
diff --git a/app/views/admin/budget_groups/create.js.erb b/app/views/admin/budget_groups/create.js.erb
new file mode 100644
index 000000000..cb926a7c6
--- /dev/null
+++ b/app/views/admin/budget_groups/create.js.erb
@@ -0,0 +1,2 @@
+$("#<%= dom_id(@budget) %>_groups").html('<%= j render("admin/budgets/groups", groups: @groups) %>');
+App.Forms.toggleLink();
\ No newline at end of file
diff --git a/app/views/admin/budget_headings/create.js.erb b/app/views/admin/budget_headings/create.js.erb
new file mode 100644
index 000000000..5d8eefb2d
--- /dev/null
+++ b/app/views/admin/budget_headings/create.js.erb
@@ -0,0 +1,2 @@
+$("#<%= dom_id(@budget_group) %>").html('<%= j render("admin/budgets/group", group: @budget_group, headings: @headings) %>');
+App.Forms.toggleLink();
\ No newline at end of file
diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb
new file mode 100644
index 000000000..3660fa0c1
--- /dev/null
+++ b/app/views/admin/budgets/_group.html.erb
@@ -0,0 +1,76 @@
+
+
+
+
+
+ <%= group.name %>
+ <%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %>
+
+
+
+ <% if headings.blank? %>
+
+
+
+
+ <%= t("admin.budgets.form.no_heading") %>
+
+
+
+ <% else %>
+
+ <%= t("admin.budgets.form.table_heading") %>
+ <%= t("admin.budgets.form.table_amount") %>
+ <%= t("admin.budgets.form.table_geozone") %>
+
+
+
+ <% end %>
+
+
+
+
+ <%= form_for [:admin, @budget, group, Budget::Heading.new], remote: true do |f| %>
+ <%= t("admin.budgets.form.heading") %>
+ <%= f.text_field :name,
+ label: false,
+ maxlength: 50,
+ placeholder: t("admin.budgets.form.heading") %>
+
+
+
+ <%= t("admin.budgets.form.amount") %>
+ <%= f.text_field :price,
+ label: false,
+ maxlength: 8,
+ placeholder: t("admin.budgets.form.amount") %>
+
+
+ <%= t("admin.budgets.form.geozone") %>
+ <%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>
+
+
+
+ <%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %>
+ <% end %>
+
+
+
+
+ <% headings.each do |heading| %>
+
+
+ <%= heading.name %>
+
+
+ <%= heading.price %>
+
+
+ <%= geozone_name_from_id heading.geozone_id %>
+
+
+ <% end %>
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/budgets/_groups.html.erb b/app/views/admin/budgets/_groups.html.erb
new file mode 100644
index 000000000..ba785ee0c
--- /dev/null
+++ b/app/views/admin/budgets/_groups.html.erb
@@ -0,0 +1,34 @@
+
+
<%= t('admin.budgets.show.groups') %>
+ <% if groups.blank? %>
+
+ <%= t("admin.budgets.form.no_groups") %>
+ <%= link_to t("admin.budgets.form.add_group"), "#",
+ class: "js-toggle-link",
+ data: { "toggle-selector" => "#new-group-form" } %>
+
+ <% else %>
+ <%= link_to t("admin.budgets.form.add_group"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#new-group-form" } %>
+ <% end %>
+
+ <%= form_for [:admin, @budget, Budget::Group.new], html: {id: "new-group-form", style: "display:none"}, remote: true do |f| %>
+
+ <% end %>
+
+ <% groups.each do |group| %>
+
+ <%= render "admin/budgets/group", group: group, headings: group.headings %>
+
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/admin/budgets/new.html.erb b/app/views/admin/budgets/new.html.erb
index 019ca460f..9ca0f34a5 100644
--- a/app/views/admin/budgets/new.html.erb
+++ b/app/views/admin/budgets/new.html.erb
@@ -23,7 +23,7 @@
<%= f.select :currency_symbol, budget_currency_symbol_select_options, {label: false} %>
- " class="button success">
+ <%= f.submit t("admin.budgets.new.create"), class: "button success" %>
<% end %>
\ No newline at end of file
diff --git a/app/views/admin/budgets/show.html.erb b/app/views/admin/budgets/show.html.erb
index 20185b2ba..847aa2f60 100644
--- a/app/views/admin/budgets/show.html.erb
+++ b/app/views/admin/budgets/show.html.erb
@@ -9,4 +9,8 @@
<%= t('admin.budgets.show.currency') %>: <%= @budget.currency_symbol %>
+
+
+
+ <%= render "groups", groups: @budget.groups %>
\ No newline at end of file
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index 812e1a45c..d8154efc1 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -74,7 +74,13 @@ en:
description: Description
phase: Phase
currency: Currency
+ show:
+ phase: Current phase
+ currency: Currency
+ groups: Groups of budget headings
+ form:
group: Group's name
+ no_groups: No groups created yet. Each user will be able to vote in only one heading per group.
add_group: Add new group
create_group: Create group
heading: Heading's name
@@ -87,9 +93,6 @@ en:
table_heading: Heading
table_amount: Amount
table_geozone: Scope of operation
- show:
- phase: Current phase
- currency: Currency
comments:
index:
filter: Filter
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 1afc01ef2..1d4ead16b 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -74,7 +74,13 @@ es:
description: Descripción
phase: Fase
currency: Divisa
+ show:
+ phase: Fase actual
+ currency: Divisa
+ groups: Grupos de partidas presupuestarias
+ form:
group: Nombre del grupo
+ no_groups: No hay grupos creados todavía. Cada usuario podrá votar en una sola partida de cada grupo.
add_group: Añadir nuevo grupo
create_group: Crear grupo
heading: Nombre de la partida
@@ -87,9 +93,6 @@ es:
table_heading: Partida
table_amount: Cantidad
table_geozone: Ámbito de actuación
- show:
- phase: Fase actual
- currency: Divisa
comments:
index:
filter: Filtro
diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb
index f38d2c9f5..123ca43e8 100644
--- a/spec/features/admin/budgets_spec.rb
+++ b/spec/features/admin/budgets_spec.rb
@@ -101,4 +101,58 @@ feature 'Admin budgets' do
end
end
+
+ context 'Manage groups and headings' do
+
+ scenario 'Create group', :js do
+ create(:budget, name: 'Yearly participatory budget')
+
+ visit admin_budgets_path
+ click_link 'Yearly participatory budget'
+
+ expect(page).to have_content 'No groups created yet.'
+
+ click_link 'Add new group'
+
+ fill_in 'budget_group_name', with: 'General improvments'
+ click_button 'Create group'
+
+ expect(page).to have_content 'Yearly participatory budget'
+ expect(page).to_not have_content 'No groups created yet.'
+
+ visit admin_budgets_path
+ click_link 'Yearly participatory budget'
+
+ expect(page).to have_content 'Yearly participatory budget'
+ expect(page).to_not have_content 'No groups created yet.'
+ end
+
+ scenario 'Create heading', :js do
+ budget = create(:budget, name: 'Yearly participatory budget')
+ group = create(:budget_group, budget: budget, name: 'Districts improvments')
+
+ visit admin_budget_path(budget)
+
+ within("#budget_group_#{group.id}") do
+ expect(page).to have_content 'This group has no assigned heading.'
+ click_link 'Add heading'
+
+ fill_in 'budget_heading_name', with: 'District 9 reconstruction'
+ fill_in 'budget_heading_price', with: '6785'
+ click_button 'Save heading'
+ end
+
+ expect(page).to_not have_content 'This group has no assigned heading.'
+
+ visit admin_budget_path(budget)
+ within("#budget_group_#{group.id}") do
+ expect(page).to_not have_content 'This group has no assigned heading.'
+
+ expect(page).to have_content 'District 9 reconstruction'
+ expect(page).to have_content '6785'
+ expect(page).to have_content 'All city'
+ end
+ end
+
+ end
end
\ No newline at end of file
From 3b5e0b55c0e6ea9c5d127f5ed5391156bc576347 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 20:45:36 +0200
Subject: [PATCH 34/41] tries to fix flacky spec
---
spec/features/notifications_spec.rb | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb
index e16dedf37..1c47ca44f 100644
--- a/spec/features/notifications_spec.rb
+++ b/spec/features/notifications_spec.rb
@@ -151,7 +151,7 @@ feature "Notifications" do
context "Proposal notification" do
- scenario "Voters should receive a notification", :js do
+ scenario "Voters should receive a notification", :js, :focus do
author = create(:user)
user1 = create(:user)
@@ -180,9 +180,10 @@ feature "Notifications" do
find(".icon-notification").click
+ notification_for_user1 = Notification.where(user: user1).first
expect(page).to have_css ".notification", count: 1
expect(page).to have_content "There is one new notification on #{proposal.title}"
- expect(page).to have_xpath "//a[@href='#{notification_path(Notification.last)}']"
+ expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user1)}']"
logout
login_as user2
@@ -190,9 +191,10 @@ feature "Notifications" do
find(".icon-notification").click
+ notification_for_user2 = Notification.where(user: user2).first
expect(page).to have_css ".notification", count: 1
expect(page).to have_content "There is one new notification on #{proposal.title}"
- expect(page).to have_xpath "//a[@href='#{notification_path(Notification.first)}']"
+ expect(page).to have_xpath "//a[@href='#{notification_path(notification_for_user2)}']"
logout
login_as user3
From 4f4a5b68e50fc518aaeb4cd3fde3d29f91434765 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 20:50:37 +0200
Subject: [PATCH 35/41] runs all spec file
---
spec/features/notifications_spec.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb
index 1c47ca44f..2504a6032 100644
--- a/spec/features/notifications_spec.rb
+++ b/spec/features/notifications_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature "Notifications" do
+feature "Notifications", :focus do
let(:author) { create :user }
let(:user) { create :user }
let(:debate) { create :debate, author: author }
@@ -151,7 +151,7 @@ feature "Notifications" do
context "Proposal notification" do
- scenario "Voters should receive a notification", :js, :focus do
+ scenario "Voters should receive a notification", :js do
author = create(:user)
user1 = create(:user)
From 24bc8cca20773098435ff227b4d36792e9b1acb6 Mon Sep 17 00:00:00 2001
From: rgarcia
Date: Wed, 3 Aug 2016 20:56:33 +0200
Subject: [PATCH 36/41] runs all specs
---
spec/features/notifications_spec.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb
index 2504a6032..5fbc51736 100644
--- a/spec/features/notifications_spec.rb
+++ b/spec/features/notifications_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature "Notifications", :focus do
+feature "Notifications" do
let(:author) { create :user }
let(:user) { create :user }
let(:debate) { create :debate, author: author }
From c84108ae601ccc4058573bfb2a3f83779fe13f23 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Fri, 12 Aug 2016 13:41:51 +0200
Subject: [PATCH 37/41] updates rails version (security fix)
---
Gemfile | 2 +-
Gemfile.lock | 62 ++++++++++++++++++++++++++--------------------------
2 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/Gemfile b/Gemfile
index 8646567dc..3f3119770 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
-gem 'rails', '4.2.7'
+gem 'rails', '4.2.7.1'
# Use PostgreSQL
gem 'pg'
# Use SCSS for stylesheets
diff --git a/Gemfile.lock b/Gemfile.lock
index 5f35de786..103ec214d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,36 +1,36 @@
GEM
remote: https://rubygems.org/
specs:
- actionmailer (4.2.7)
- actionpack (= 4.2.7)
- actionview (= 4.2.7)
- activejob (= 4.2.7)
+ actionmailer (4.2.7.1)
+ actionpack (= 4.2.7.1)
+ actionview (= 4.2.7.1)
+ activejob (= 4.2.7.1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
- actionpack (4.2.7)
- actionview (= 4.2.7)
- activesupport (= 4.2.7)
+ actionpack (4.2.7.1)
+ actionview (= 4.2.7.1)
+ activesupport (= 4.2.7.1)
rack (~> 1.6)
rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (4.2.7)
- activesupport (= 4.2.7)
+ actionview (4.2.7.1)
+ activesupport (= 4.2.7.1)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- activejob (4.2.7)
- activesupport (= 4.2.7)
+ activejob (4.2.7.1)
+ activesupport (= 4.2.7.1)
globalid (>= 0.3.0)
- activemodel (4.2.7)
- activesupport (= 4.2.7)
+ activemodel (4.2.7.1)
+ activesupport (= 4.2.7.1)
builder (~> 3.1)
- activerecord (4.2.7)
- activemodel (= 4.2.7)
- activesupport (= 4.2.7)
+ activerecord (4.2.7.1)
+ activemodel (= 4.2.7.1)
+ activesupport (= 4.2.7.1)
arel (~> 6.0)
- activesupport (4.2.7)
+ activesupport (4.2.7.1)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
@@ -174,7 +174,7 @@ GEM
rspec (~> 3.0)
ruby-progressbar (~> 1.4)
geocoder (1.3.7)
- globalid (0.3.6)
+ globalid (0.3.7)
activesupport (>= 4.1.0)
groupdate (3.0.1)
activesupport (>= 3)
@@ -290,16 +290,16 @@ GEM
rack
rack-test (0.6.3)
rack (>= 1.0)
- rails (4.2.7)
- actionmailer (= 4.2.7)
- actionpack (= 4.2.7)
- actionview (= 4.2.7)
- activejob (= 4.2.7)
- activemodel (= 4.2.7)
- activerecord (= 4.2.7)
- activesupport (= 4.2.7)
+ rails (4.2.7.1)
+ actionmailer (= 4.2.7.1)
+ actionpack (= 4.2.7.1)
+ actionview (= 4.2.7.1)
+ activejob (= 4.2.7.1)
+ activemodel (= 4.2.7.1)
+ activerecord (= 4.2.7.1)
+ activesupport (= 4.2.7.1)
bundler (>= 1.3.0, < 2.0)
- railties (= 4.2.7)
+ railties (= 4.2.7.1)
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
@@ -309,9 +309,9 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
- railties (4.2.7)
- actionpack (= 4.2.7)
- activesupport (= 4.2.7)
+ railties (4.2.7.1)
+ actionpack (= 4.2.7.1)
+ activesupport (= 4.2.7.1)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.16.0)
@@ -485,7 +485,7 @@ DEPENDENCIES
pg_search
poltergeist
quiet_assets
- rails (= 4.2.7)
+ rails (= 4.2.7.1)
redcarpet
responders
rinku
From 345e34d4229d05cb783c4ad8ed35febc41bf6681 Mon Sep 17 00:00:00 2001
From: kikito
Date: Mon, 29 Aug 2016 16:49:52 +0200
Subject: [PATCH 38/41] adds ckeditor config
---
config/initializers/ckeditor.rb | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 config/initializers/ckeditor.rb
diff --git a/config/initializers/ckeditor.rb b/config/initializers/ckeditor.rb
new file mode 100644
index 000000000..58e119048
--- /dev/null
+++ b/config/initializers/ckeditor.rb
@@ -0,0 +1,4 @@
+Ckeditor.setup do |config|
+ config.assets_languages = I18n.available_locales.map(&:to_s)
+ config.assets_plugins = []
+end
From 7ad4a212296caccd47495fa856c4877b1213edc3 Mon Sep 17 00:00:00 2001
From: kikito
Date: Tue, 30 Aug 2016 12:05:46 +0200
Subject: [PATCH 39/41] Tries to make ckeditor work correctly with the asset
pipeline
Reference: https://github.com/galetahub/ckeditor/issues/519
---
app/assets/javascripts/application.js | 2 +-
app/assets/javascripts/ckeditor/loader.js.erb | 3 +++
config/initializers/assets.rb | 2 +-
3 files changed, 5 insertions(+), 2 deletions(-)
create mode 100644 app/assets/javascripts/ckeditor/loader.js.erb
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index ca79ceb8b..7fb92b5e3 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -16,7 +16,7 @@
//= require jquery-ui/datepicker-es
//= require foundation
//= require turbolinks
-//= require ckeditor/init
+//= require ckeditor/loader
//= require_directory ./ckeditor
//= require social-share-button
//= require initial
diff --git a/app/assets/javascripts/ckeditor/loader.js.erb b/app/assets/javascripts/ckeditor/loader.js.erb
new file mode 100644
index 000000000..66e1d8347
--- /dev/null
+++ b/app/assets/javascripts/ckeditor/loader.js.erb
@@ -0,0 +1,3 @@
+//= require ckeditor/init
+
+CKEDITOR.config.customConfig = '<%= javascript_path 'ckeditor/config.js' %>';
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index 942ba99c8..e5fc916f0 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -9,7 +9,7 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
-Rails.application.config.assets.precompile += %w( ckeditor/* )
+Rails.application.config.assets.precompile += %w( ckeditor/config.js )
Rails.application.config.assets.precompile += %w( ie_lt9.js )
Rails.application.config.assets.precompile += %w( stat_graphs.js )
Rails.application.config.assets.precompile += %w( print.css )
From fb31a4782f8eed7009db30f51c2a69627c9b3025 Mon Sep 17 00:00:00 2001
From: kikito
Date: Tue, 30 Aug 2016 18:26:51 +0200
Subject: [PATCH 40/41] downgrades sprockets to 3.6.3 to avoid warnings
---
Gemfile | 3 +++
Gemfile.lock | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 3f3119770..1819992d3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -19,6 +19,9 @@ gem 'jquery-ui-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
+# Fix sprockets on the
+gem 'sprockets', '~> 3.6.3'
+
gem 'devise', '~> 3.5.7'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
diff --git a/Gemfile.lock b/Gemfile.lock
index 103ec214d..121d7b86e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -375,7 +375,7 @@ GEM
spring (1.7.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
- sprockets (3.7.0)
+ sprockets (3.6.3)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-es6 (0.9.0)
@@ -496,6 +496,7 @@ DEPENDENCIES
social-share-button
spring
spring-commands-rspec
+ sprockets (~> 3.6.3)
tolk
turbolinks
turnout
From f24886560b2f6636fc5cd958ecbb04a6e2909aa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?=
Date: Thu, 1 Sep 2016 12:46:43 +0200
Subject: [PATCH 41/41] removes unused i18n entry
---
config/locales/admin.en.yml | 1 -
config/locales/admin.es.yml | 1 -
2 files changed, 2 deletions(-)
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index d8154efc1..78a3a6d6c 100755
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -89,7 +89,6 @@ en:
save_heading: Save heading
no_heading: This group has no assigned heading.
geozone: Scope of operation
- no_geozone: Does not apply
table_heading: Heading
table_amount: Amount
table_geozone: Scope of operation
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 1d4ead16b..496a0208d 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -89,7 +89,6 @@ es:
save_heading: Guardar partida
no_heading: Este grupo no tiene ninguna partida asignada.
geozone: Ámbito de actuación
- no_geozone: No aplica
table_heading: Partida
table_amount: Cantidad
table_geozone: Ámbito de actuación