From ff1fced6099bd0379d096e0da96a2f55e6645516 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 28 Mar 2018 10:14:57 -0400 Subject: [PATCH 01/85] Update Dockerfile to install Headless Chrome --- Dockerfile | 14 ++++++++++++-- spec/rails_helper.rb | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 880d17e43..55b0b31ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,8 @@ +# Use Ruby 2.3.6 as base image FROM ruby:2.3.6 # Install essential Linux packages -RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client nodejs imagemagick sudo +RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client nodejs imagemagick sudo libxss1 libappindicator1 libindicator7 unzip # Files created inside the container repect the ownership RUN adduser --shell /bin/bash --disabled-password --gecos "" consul \ @@ -34,9 +35,18 @@ COPY Gemfile_custom Gemfile_custom # Prevent bundler warnings; ensure that the bundler version executed is >= that which created Gemfile.lock RUN gem install bundler -# Finish establishing our Ruby enviornment +# Finish establishing our Ruby environment RUN bundle install --full-index +# Install Chromium and ChromeDriver for E2E integration tests +RUN apt-get update -qq && apt-get install -y chromium-browser +RUN wget -N http://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip +RUN unzip chromedriver_linux64.zip +RUN chmod +x chromedriver +RUN mv -f chromedriver /usr/local/share/chromedriver +RUN ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver +RUN ln -s /usr/local/share/chromedriver /usr/bin/chromedriver + # Copy the Rails application into place COPY . . diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 8731eb670..1385490c8 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -32,7 +32,7 @@ end Capybara.register_driver :headless_chrome do |app| capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( - chromeOptions: { args: %w(headless window-size=1200,600) } + chromeOptions: { args: %w(headless no-sandbox window-size=1200,600) } ) Capybara::Selenium::Driver.new( From 45cbec7736a8e633a637db6bd32dabc179b81b90 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 28 Mar 2018 10:15:56 -0400 Subject: [PATCH 02/85] Set DEBIAN_FRONTEND as 'noninteractive' to fix debconf warnings --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 55b0b31ca..611f31292 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ # Use Ruby 2.3.6 as base image FROM ruby:2.3.6 +ENV DEBIAN_FRONTEND noninteractive + # Install essential Linux packages RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client nodejs imagemagick sudo libxss1 libappindicator1 libindicator7 unzip From 9836bb63c3631cc51af0473544764d5a5a113661 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 28 Mar 2018 10:54:18 -0400 Subject: [PATCH 03/85] Install memcached when building Docker container --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 611f31292..27905a562 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,8 @@ FROM ruby:2.3.6 ENV DEBIAN_FRONTEND noninteractive # Install essential Linux packages -RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client nodejs imagemagick sudo libxss1 libappindicator1 libindicator7 unzip +RUN apt-get update -qq +RUN apt-get install -y build-essential libpq-dev postgresql-client nodejs imagemagick sudo libxss1 libappindicator1 libindicator7 unzip memcached # Files created inside the container repect the ownership RUN adduser --shell /bin/bash --disabled-password --gecos "" consul \ From 812b43a74be8c6b91e53a1dd9b21589005a959fb Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 7 Jun 2018 14:10:50 -0400 Subject: [PATCH 04/85] Replace deprecated `chromium-browser` package with `chromium` --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 27905a562..158bf7212 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ RUN gem install bundler RUN bundle install --full-index # Install Chromium and ChromeDriver for E2E integration tests -RUN apt-get update -qq && apt-get install -y chromium-browser +RUN apt-get update -qq && apt-get install -y chromium RUN wget -N http://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip RUN unzip chromedriver_linux64.zip RUN chmod +x chromedriver @@ -55,5 +55,5 @@ COPY . . # Define the script we want run once the container boots # Use the "exec" form of CMD so our script shuts down gracefully on SIGTERM (i.e. `docker stop`) -#CMD [ "config/containers/app_cmd.sh" ] +# CMD [ "config/containers/app_cmd.sh" ] CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"] From 81d8b9b9ed757b6199a5deb7d0d22f2bc8e912d6 Mon Sep 17 00:00:00 2001 From: iagirre Date: Thu, 16 Nov 2017 16:36:09 +0100 Subject: [PATCH 05/85] Admin menu added to management --- app/views/layouts/management.html.erb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/views/layouts/management.html.erb b/app/views/layouts/management.html.erb index 4dc4aec12..3fcf83f6e 100644 --- a/app/views/layouts/management.html.erb +++ b/app/views/layouts/management.html.erb @@ -29,6 +29,19 @@ + <% if current_administrator? %> +
+ +
+ +
+ +
+ <% end %> From 7a7ae5fa2ee5285f832efba8e050aeeaeb5b8a02 Mon Sep 17 00:00:00 2001 From: iagirre Date: Fri, 17 Nov 2017 11:41:44 +0100 Subject: [PATCH 06/85] The admin menu is shown in the management section if the user who logged in is an admin --- app/controllers/management/base_controller.rb | 13 ++++++++++++- app/helpers/users_helper.rb | 4 ++-- app/views/layouts/management.html.erb | 8 ++++---- app/views/shared/_admin_login_items.html.erb | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/controllers/management/base_controller.rb b/app/controllers/management/base_controller.rb index bcebfebaa..c5d8edec3 100644 --- a/app/controllers/management/base_controller.rb +++ b/app/controllers/management/base_controller.rb @@ -6,6 +6,7 @@ class Management::BaseController < ActionController::Base helper_method :managed_user helper_method :current_user + helper_method :user_signed_in private @@ -22,7 +23,10 @@ class Management::BaseController < ActionController::Base end def managed_user - @managed_user ||= Verification::Management::ManagedUser.find(session[:document_type], session[:document_number]) + @managed_user ||= Verification::Management::ManagedUser.find( + session[:document_type], + session[:document_number] + ) end def check_verified_user(alert_msg) @@ -49,4 +53,11 @@ class Management::BaseController < ActionController::Base def clear_password session[:new_password] = nil end + + def user_signed_in + if current_manager + @user_signed_in = User.find(session[:manager]["login"].last(1)) + end + end + end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 980dd1e39..c0574f78a 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -52,8 +52,8 @@ module UsersHelper current_user && current_user.manager? end - def show_admin_menu? - current_administrator? || current_moderator? || current_valuator? || current_manager? + def show_admin_menu?(user = nil) + current_administrator? || current_moderator? || current_valuator? || current_manager? || user.administrator? end def interests_title_text(user) diff --git a/app/views/layouts/management.html.erb b/app/views/layouts/management.html.erb index 3fcf83f6e..9fc4f411f 100644 --- a/app/views/layouts/management.html.erb +++ b/app/views/layouts/management.html.erb @@ -29,14 +29,14 @@ - <% if current_administrator? %> + <% if user_signed_in.administrator? %>
diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 3fbb34fcc..85407398a 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -1,4 +1,4 @@ -<% if show_admin_menu? %> +<% if show_admin_menu?(current_user) %>
  • <%= link_to t("layouts.header.administration_menu"), "#", rel: "nofollow", class: "hide-for-small-only" %>
  • - <% if user_signed_in.administrator? %> + <% if show_admin_menu?(manager_logged_in) %>
    From 6e238ae252a39258b97032dde74bab41ffda2c6f Mon Sep 17 00:00:00 2001 From: iagirre Date: Mon, 20 Nov 2017 09:39:57 +0100 Subject: [PATCH 09/85] Changed redirection when signing out from management section --- app/controllers/users/sessions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index 5605e3a00..d16f9c87e 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -11,7 +11,7 @@ class Users::SessionsController < Devise::SessionsController end def after_sign_out_path_for(resource) - request.referer.present? ? request.referer : super + request.referer.present? && !request.referer.match("management") ? request.referer : super end def verifying_via_email? From 8c8668a83c285f9b3eabd804df6b98f128588a5d Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 13 Jul 2018 18:13:55 -0400 Subject: [PATCH 10/85] Use ChromeDriver 2.40 when building container --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 158bf7212..52547d243 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,7 +43,7 @@ RUN bundle install --full-index # Install Chromium and ChromeDriver for E2E integration tests RUN apt-get update -qq && apt-get install -y chromium -RUN wget -N http://chromedriver.storage.googleapis.com/2.37/chromedriver_linux64.zip +RUN wget -N http://chromedriver.storage.googleapis.com/2.40/chromedriver_linux64.zip RUN unzip chromedriver_linux64.zip RUN chmod +x chromedriver RUN mv -f chromedriver /usr/local/share/chromedriver From 335f78ae240467c4065d0a8a5343de96affc4110 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 13 Jun 2018 11:26:20 -0400 Subject: [PATCH 11/85] Migrate DB to add moderation attrs to `budget_investments` table --- ...20180613143922_add_moderation_attrs_to_investments.rb | 9 +++++++++ db/schema.rb | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 db/migrate/20180613143922_add_moderation_attrs_to_investments.rb diff --git a/db/migrate/20180613143922_add_moderation_attrs_to_investments.rb b/db/migrate/20180613143922_add_moderation_attrs_to_investments.rb new file mode 100644 index 000000000..ebb4fdf1a --- /dev/null +++ b/db/migrate/20180613143922_add_moderation_attrs_to_investments.rb @@ -0,0 +1,9 @@ +class AddModerationAttrsToInvestments < ActiveRecord::Migration + def change + change_table :budget_investments do |t| + t.datetime :confirmed_hide_at + t.datetime :ignored_flag_at + t.integer :flags_count, default: 0 + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 5e9247806..1fa940235 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -198,6 +198,9 @@ ActiveRecord::Schema.define(version: 20180711224810) do t.integer "community_id" t.boolean "visible_to_valuators", default: false t.integer "valuator_group_assignments_count", default: 0 + t.datetime "confirmed_hide_at" + t.datetime "ignored_flag_at" + t.integer "flags_count", default: 0 end add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree From 4737664f6e273e58b8e562aa13b20caed0be6cec Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 13 Jun 2018 11:44:24 -0400 Subject: [PATCH 12/85] Include routes for investments moderation --- config/routes/admin.rb | 2 ++ config/routes/budget.rb | 7 ++++++- config/routes/moderation.rb | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 001456f6e..5ea78fcd5 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -78,6 +78,7 @@ namespace :admin do end resources :tags, only: [:index, :create, :update, :destroy] + resources :officials, only: [:index, :edit, :update, :destroy] do get :search, on: :collection end @@ -93,6 +94,7 @@ namespace :admin do get :search, on: :collection get :summary, on: :collection end + resources :valuator_groups resources :managers, only: [:index, :create, :destroy] do diff --git a/config/routes/budget.rb b/config/routes/budget.rb index aef2c1413..b3422744f 100644 --- a/config/routes/budget.rb +++ b/config/routes/budget.rb @@ -1,7 +1,12 @@ resources :budgets, only: [:show, :index] do resources :groups, controller: "budgets/groups", only: [:show] resources :investments, controller: "budgets/investments", only: [:index, :new, :create, :show, :destroy] do - member { post :vote } + member do + post :vote + put :flag + put :unflag + end + collection { get :suggest } end diff --git a/config/routes/moderation.rb b/config/routes/moderation.rb index 90dc9be27..f68af0598 100644 --- a/config/routes/moderation.rb +++ b/config/routes/moderation.rb @@ -27,4 +27,9 @@ namespace :moderation do put :hide, on: :member put :moderate, on: :collection end + + resources :budget_investments, only: :index do + put :hide, on: :member + put :moderate, on: :collection + end end From bcb0b9fbfaea4c667e1814032c5bf7173cd2629b Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 13 Jun 2018 13:41:21 -0400 Subject: [PATCH 13/85] Enable moderation abilities for Budget::Investment model --- app/models/abilities/administrator.rb | 6 ++++++ app/models/abilities/common.rb | 3 +++ app/models/abilities/moderation.rb | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 6f8a70b5e..08e4ae1fa 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -17,6 +17,9 @@ module Abilities can :restore, Legislation::Proposal cannot :restore, Legislation::Proposal, hidden_at: nil + can :restore, Budget::Investment + cannot :restore, Budget::Investment, hidden_at: nil + can :restore, User cannot :restore, User, hidden_at: nil @@ -32,6 +35,9 @@ module Abilities can :confirm_hide, Legislation::Proposal cannot :confirm_hide, Legislation::Proposal, hidden_at: nil + can :confirm_hide, Budget::Investment + cannot :confirm_hide, Budget::Investment, hidden_at: nil + can :confirm_hide, User cannot :confirm_hide, User, hidden_at: nil diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index d8d716ec2..7c84089b4 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -46,6 +46,9 @@ module Abilities can [:flag, :unflag], Legislation::Proposal cannot [:flag, :unflag], Legislation::Proposal, author_id: user.id + can [:flag, :unflag], Budget::Investment + cannot [:flag, :unflag], Budget::Investment, author_id: user.id + can [:create, :destroy], Follow can [:destroy], Document, documentable: { author_id: user.id } diff --git a/app/models/abilities/moderation.rb b/app/models/abilities/moderation.rb index 801e752ed..86f44f25e 100644 --- a/app/models/abilities/moderation.rb +++ b/app/models/abilities/moderation.rb @@ -63,6 +63,15 @@ module Abilities cannot :moderate, ProposalNotification, author_id: user.id can :index, ProposalNotification + + can :hide, Budget::Investment, hidden_at: nil + cannot :hide, Budget::Investment, author_id: user.id + + can :ignore_flag, Budget::Investment, ignored_flag_at: nil, hidden_at: nil + cannot :ignore_flag, Budget::Investment, author_id: user.id + + can :moderate, Budget::Investment + cannot :moderate, Budget::Investment, author_id: user.id end end end From 8ef3e81e03b03774cc4d8cee3ac03828d90e160f Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 13 Jun 2018 13:54:18 -0400 Subject: [PATCH 14/85] Adapt public views for flagging/unflagging investments --- app/controllers/stats_controller.rb | 1 + .../budgets/investments/_actions.html.erb | 10 + .../investments/_flag_actions.html.erb | 25 ++ .../investments/_investment_show.html.erb | 341 +++++++++--------- .../investments/_refresh_flag_actions.js.erb | 1 + 5 files changed, 215 insertions(+), 163 deletions(-) create mode 100644 app/views/budgets/investments/_actions.html.erb create mode 100644 app/views/budgets/investments/_flag_actions.html.erb create mode 100644 app/views/budgets/investments/_refresh_flag_actions.js.erb diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 7130e661d..7bb872257 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -14,6 +14,7 @@ class StatsController < ApplicationController @debate_votes = daily_cache('debate_votes') { Vote.where(votable_type: 'Debate').count } @proposal_votes = daily_cache('proposal_votes') { Vote.where(votable_type: 'Proposal').count } @comment_votes = daily_cache('comment_votes') { Vote.where(votable_type: 'Comment').count } + @investment_votes = daily_cache('budget_investment_votes') { Vote.where(votable_type: 'Budget::Investment').count } @votes = daily_cache('votes') { Vote.count } @verified_users = daily_cache('verified_users') { User.with_hidden.level_two_or_three_verified.count } diff --git a/app/views/budgets/investments/_actions.html.erb b/app/views/budgets/investments/_actions.html.erb new file mode 100644 index 000000000..a464d7495 --- /dev/null +++ b/app/views/budgets/investments/_actions.html.erb @@ -0,0 +1,10 @@ +<% if can? :hide, investment %> + <%= link_to t("admin.actions.hide").capitalize, hide_moderation_budget_investment_path(investment), + method: :put, remote: true, data: { confirm: t("admin.actions.confirm") } %> +<% end %> + +<% if can? :hide, investment.author %> +  |  + <%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(investment.author_id), + method: :put, data: { confirm: t("admin.actions.confirm") } %> +<% end %> diff --git a/app/views/budgets/investments/_flag_actions.html.erb b/app/views/budgets/investments/_flag_actions.html.erb new file mode 100644 index 000000000..8627dfe94 --- /dev/null +++ b/app/views/budgets/investments/_flag_actions.html.erb @@ -0,0 +1,25 @@ + + <% if show_flag_action? investment %> + + + + + <%= link_to t('shared.flag'), flag_budget_investment_path(investment.budget, investment.id), + method: :put, + remote: true, + id: "flag-investment-#{ investment.id }" %> + + <% end %> + + <% if show_unflag_action? investment %> + + + + + <%= link_to t('shared.unflag'), unflag_budget_investment_path(investment.budget, investment.id), + method: :put, + remote: true, + id: "unflag-investment-#{ investment.id }" %> + + <% end %> + diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index acca21a80..2f3528653 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -7,180 +7,195 @@ og_image_url: (investment.image.present? ? investment.image_url(:thumb) : nil) %> <% end %> -
    +<% cache [locale_and_user_status(investment), + investment, + investment.author, + Flag.flagged?(current_user, investment), + @investment_votes] do %> +
    -
    -
    - <%= back_link_to budget_investments_path(investment.budget, heading_id: investment.heading) %> +
    +
    + <%= back_link_to budget_investments_path(investment.budget, heading_id: investment.heading) %> -

    <%= investment.title %>

    -
    - <%= render '/shared/author_info', resource: investment %> +

    <%= investment.title %>

    +
    + <%= render '/shared/author_info', resource: investment %> -  •  - <%= l investment.created_at.to_date %> -  •  - <%= investment.heading.name %> +  •  + <%= l investment.created_at.to_date %> +  •  + <%= investment.heading.name %> +  •  + + <%= render 'budgets/investments/flag_actions', investment: @investment %> + +
    + +
    + + <%= render_image(investment.image, :large, true) if investment.image.present? %> + +

    + <%= t("budgets.investments.show.code_html", code: investment.id) %> +

    + + <%= safe_html_with_links investment.description.html_safe %> + + <% if feature?(:map) && map_location_available?(@investment.map_location) %> +
    + <%= render_map(@investment.map_location, "budget_investment", false, nil) %> +
    + <% end %> + + <% if investment.location.present? %> +

    + <%= t("budgets.investments.show.location_html", location: investment.location) %> +

    + <% end %> + + <% if investment.organization_name.present? %> +

    + <%= t("budgets.investments.show.organization_name_html", name: investment.organization_name) %> +

    + <% end %> + + <% if feature?(:allow_attached_documents) %> + <%= render 'documents/documents', + documents: investment.documents, + max_documents_allowed: Budget::Investment.max_documents_allowed %> + <% end %> + + <%= render 'shared/tags', taggable: investment %> + + <% if investment.external_url.present? %> + + <% end %> + + <% if investment.should_show_unfeasibility_explanation? %> +

    <%= t('budgets.investments.show.unfeasibility_explanation') %>

    +

    <%= investment.unfeasibility_explanation %>

    + <% end %> + + <% if investment.should_show_price_explanation? %> +

    <%= t('budgets.investments.show.price_explanation') %>

    +

    <%= investment.price_explanation %>

    + <% end %> + + <%= render 'relationable/related_content', relationable: @investment %> + +
    + <%= render "budgets/investments/actions", investment: @investment %> +
    -
    +
    - - -
    -
    + +
    + +<% end %> diff --git a/app/views/budgets/investments/_refresh_flag_actions.js.erb b/app/views/budgets/investments/_refresh_flag_actions.js.erb new file mode 100644 index 000000000..07cf8d30a --- /dev/null +++ b/app/views/budgets/investments/_refresh_flag_actions.js.erb @@ -0,0 +1 @@ +App.Flaggable.update("<%= dom_id(@investment) %>", "<%= j render("budgets/investments/flag_actions", investment: @investment) %>") From 7bb1da18044af16486de9744f699a7d19372e460 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Sun, 17 Jun 2018 23:05:18 -0400 Subject: [PATCH 15/85] Adapt backend to enable flagging/unflagging investments --- app/controllers/concerns/flag_actions.rb | 22 ++++++++++++++++++---- app/models/budget/investment.rb | 1 + app/models/user.rb | 2 ++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/controllers/concerns/flag_actions.rb b/app/controllers/concerns/flag_actions.rb index 3f5d0b2c7..da637407a 100644 --- a/app/controllers/concerns/flag_actions.rb +++ b/app/controllers/concerns/flag_actions.rb @@ -3,18 +3,32 @@ module FlagActions def flag Flag.flag(current_user, flaggable) - respond_with flaggable, template: "#{controller_name}/_refresh_flag_actions" + + if controller_name == 'investments' + respond_with flaggable, template: "budgets/#{controller_name}/_refresh_flag_actions" + else + respond_with flaggable, template: "#{controller_name}/_refresh_flag_actions" + end end def unflag Flag.unflag(current_user, flaggable) - respond_with flaggable, template: "#{controller_name}/_refresh_flag_actions" + + if controller_name == 'investments' + respond_with flaggable, template: "budgets/#{controller_name}/_refresh_flag_actions" + else + respond_with flaggable, template: "#{controller_name}/_refresh_flag_actions" + end end private def flaggable - instance_variable_get("@#{resource_model.to_s.downcase}") + if resource_model.to_s == 'Budget::Investment' + instance_variable_get("@investment") + else + instance_variable_get("@#{resource_model.to_s.downcase}") + end end -end \ No newline at end of file +end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 6a9b95cd4..292200f6a 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -23,6 +23,7 @@ class Budget include Relationable include Notifiable include Filterable + include Flaggable belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :heading diff --git a/app/models/user.rb b/app/models/user.rb index 67fe5d104..4b999207d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -182,6 +182,7 @@ class User < ActiveRecord::Base debates_ids = Debate.where(author_id: id).pluck(:id) comments_ids = Comment.where(user_id: id).pluck(:id) proposal_ids = Proposal.where(author_id: id).pluck(:id) + investment_ids = Budget::Investment.where(author_id: id).pluck(:id) proposal_notification_ids = ProposalNotification.where(author_id: id).pluck(:id) hide @@ -189,6 +190,7 @@ class User < ActiveRecord::Base Debate.hide_all debates_ids Comment.hide_all comments_ids Proposal.hide_all proposal_ids + Budget::Investment.hide_all investment_ids ProposalNotification.hide_all proposal_notification_ids end From 1990092fdf3d46abc9ba73117e35b552d88c869f Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 18 Jun 2018 01:16:26 -0400 Subject: [PATCH 16/85] Allow moderators to hide inappropriate investments --- app/assets/javascripts/application.js | 1 + .../moderator_budget_investments.js.coffee | 8 +++++++ app/controllers/concerns/polymorphic.rb | 6 ++++- .../budgets/investments_controller.rb | 24 +++++++++++++++++++ .../budgets/investments/hide.js.erb | 3 +++ config/routes/moderation.rb | 2 +- 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 app/assets/javascripts/moderator_budget_investments.js.coffee create mode 100644 app/controllers/moderation/budgets/investments_controller.rb create mode 100644 app/views/moderation/budgets/investments/hide.js.erb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index a9e44d249..3cd91467b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -33,6 +33,7 @@ //= require moderator_comment //= require moderator_debates //= require moderator_proposals +//= require moderator_budget_investments //= require moderator_proposal_notifications //= require prevent_double_submission //= require gettext diff --git a/app/assets/javascripts/moderator_budget_investments.js.coffee b/app/assets/javascripts/moderator_budget_investments.js.coffee new file mode 100644 index 000000000..612a058a4 --- /dev/null +++ b/app/assets/javascripts/moderator_budget_investments.js.coffee @@ -0,0 +1,8 @@ +App.ModeratorBudgetInvestments = + + add_class_faded: (id) -> + $("##{id}").addClass("faded") + $("#comments").addClass("faded") + + hide_moderator_actions: (id) -> + $("##{id} .js-moderator-investment-actions:first").hide() diff --git a/app/controllers/concerns/polymorphic.rb b/app/controllers/concerns/polymorphic.rb index 8fd4ab312..0e25b4231 100644 --- a/app/controllers/concerns/polymorphic.rb +++ b/app/controllers/concerns/polymorphic.rb @@ -3,7 +3,11 @@ module Polymorphic private def resource - @resource ||= instance_variable_get("@#{resource_name}") + if resource_model.to_s == 'Budget::Investment' + @resource ||= instance_variable_get("@investment") + else + @resource ||= instance_variable_get("@#{resource_name}") + end end def resource_name diff --git a/app/controllers/moderation/budgets/investments_controller.rb b/app/controllers/moderation/budgets/investments_controller.rb new file mode 100644 index 000000000..7f33058e8 --- /dev/null +++ b/app/controllers/moderation/budgets/investments_controller.rb @@ -0,0 +1,24 @@ +class Moderation::Budgets::InvestmentsController < Moderation::BaseController + include FeatureFlags + include ModerateActions + + has_filters %w{pending_flag_review all with_ignored_flag}, only: :index + has_orders %w{flags created_at}, only: :index + + feature_flag :budgets + + before_action :load_resources, only: [:index, :moderate] + + load_and_authorize_resource class: 'Budget::Investment' + + private + + def resource_name + 'budget_investment' + end + + def resource_model + Budget::Investment + end + +end diff --git a/app/views/moderation/budgets/investments/hide.js.erb b/app/views/moderation/budgets/investments/hide.js.erb new file mode 100644 index 000000000..9365b3837 --- /dev/null +++ b/app/views/moderation/budgets/investments/hide.js.erb @@ -0,0 +1,3 @@ +var investment_id = '<%= dom_id(@investment) %>' +App.ModeratorBudgetInvestments.add_class_faded(investment_id) +App.ModeratorBudgetInvestments.hide_moderator_actions(investment_id) diff --git a/config/routes/moderation.rb b/config/routes/moderation.rb index f68af0598..e6b0020cd 100644 --- a/config/routes/moderation.rb +++ b/config/routes/moderation.rb @@ -28,7 +28,7 @@ namespace :moderation do put :moderate, on: :collection end - resources :budget_investments, only: :index do + resources :budget_investments, only: :index, controller: 'budgets/investments' do put :hide, on: :member put :moderate, on: :collection end From 4da23716bb7a381377ef7776bc3253bee89d64f9 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 18 Jun 2018 10:12:09 -0400 Subject: [PATCH 17/85] Allow admins to moderate investments --- .../hidden_budget_investments_controller.rb | 34 +++++++++++++ app/helpers/admin_helper.rb | 2 +- app/views/admin/_menu.html.erb | 6 +++ .../hidden_budget_investments/index.html.erb | 49 +++++++++++++++++++ config/locales/en/admin.yml | 10 ++++ config/locales/es/admin.yml | 10 ++++ config/routes/admin.rb | 7 +++ 7 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/hidden_budget_investments_controller.rb create mode 100644 app/views/admin/hidden_budget_investments/index.html.erb diff --git a/app/controllers/admin/hidden_budget_investments_controller.rb b/app/controllers/admin/hidden_budget_investments_controller.rb new file mode 100644 index 000000000..439f3c722 --- /dev/null +++ b/app/controllers/admin/hidden_budget_investments_controller.rb @@ -0,0 +1,34 @@ +class Admin::HiddenBudgetInvestmentsController < Admin::BaseController + include FeatureFlags + + has_filters %w{all with_confirmed_hide without_confirmed_hide}, only: :index + + feature_flag :budgets + + before_action :load_investment, only: [:confirm_hide, :restore] + + def index + @investments = Budget::Investment.only_hidden.send(@current_filter) + .order(hidden_at: :desc) + .page(params[:page]) + end + + def confirm_hide + @investment.confirm_hide + redirect_to request.query_parameters.merge(action: :index) + end + + def restore + @investment.restore + @investment.ignore_flag + Activity.log(current_user, :restore, @investment) + redirect_to request.query_parameters.merge(action: :index) + end + + private + + def load_investment + @investment = Budget::Investment.with_hidden.find(params[:id]) + end + +end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 988d03a00..1b6783bfa 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -13,7 +13,7 @@ module AdminHelper end def menu_moderated_content? - ["proposals", "debates", "comments", "hidden_users", "activity"].include?(controller_name) && controller.class.parent != Admin::Legislation + ["proposals", "debates", "comments", "hidden_users", "activity", "hidden_budget_investments"].include?(controller_name) && controller.class.parent != Admin::Legislation end def menu_budget? diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index b830acb46..6d5e32075 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -145,6 +145,12 @@ <% end %> + <% if feature?(:budgets) %> +
  • > + <%= link_to t("admin.menu.hidden_budget_investments"), admin_hidden_budget_investments_path %> +
  • + <% end %> +
  • > <%= link_to t("admin.menu.hidden_comments"), admin_comments_path %>
  • diff --git a/app/views/admin/hidden_budget_investments/index.html.erb b/app/views/admin/hidden_budget_investments/index.html.erb new file mode 100644 index 000000000..68f5f6ce6 --- /dev/null +++ b/app/views/admin/hidden_budget_investments/index.html.erb @@ -0,0 +1,49 @@ +

    <%= t("admin.hidden_budget_investments.index.title") %>

    +

    <%= t("admin.shared.moderated_content") %>

    + +<%= render 'shared/filter_subnav', i18n_namespace: "admin.hidden_budget_investments.index" %> + +<% if @investments.any? %> +

    <%= page_entries_info @investments %>

    + + + + + + + + + <% @investments.each do |investment| %> + + + + + + <% end %> + +
    <%= t("admin.shared.title") %><%= t("admin.shared.description") %><%= t("admin.shared.actions") %>
    + <%= investment.title %> + +
    + <%= investment.description %> +
    +
    + <%= link_to t("admin.actions.restore"), + restore_admin_hidden_budget_investment_path(investment, request.query_parameters), + method: :put, + data: { confirm: t("admin.actions.confirm") }, + class: "button hollow warning" %> + <% unless investment.confirmed_hide? %> + <%= link_to t("admin.actions.confirm_hide"), + confirm_hide_admin_hidden_budget_investment_path(investment, request.query_parameters), + method: :put, + class: "button" %> + <% end %> +
    + + <%= paginate @investments %> +<% else %> +
    + <%= t("admin.hidden_budget_investments.index.no_hidden_budget_investments") %> +
    +<% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index ac23897df..c57c98dc2 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -343,6 +343,15 @@ en: hidden_at: 'Hidden at:' registered_at: 'Registered at:' title: Activity of user (%{user}) + hidden_budget_investments: + index: + filter: Filter + filters: + all: All + with_confirmed_hide: Confirmed + without_confirmed_hide: Pending + title: Hidden budgets investments + no_hidden_budget_investments: There are no hidden budget investments legislation: processes: create: @@ -512,6 +521,7 @@ en: hidden_comments: Hidden comments hidden_debates: Hidden debates hidden_proposals: Hidden proposals + hidden_budget_investments: Hidden budget investments hidden_proposal_notifications: Hidden proposal notifications hidden_users: Hidden users administrators: Administrators diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 8929f9e3b..5e1aa7804 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -343,6 +343,15 @@ es: hidden_at: 'Bloqueado:' registered_at: 'Fecha de alta:' title: Actividad del usuario (%{user}) + hidden_budget_investments: + index: + filter: Filtro + filters: + all: Todos + with_confirmed_hide: Confirmados + without_confirmed_hide: Pendientes + title: Proyectos de gasto ocultos + no_hidden_budget_investments: No hay proyectos de gasto ocultos legislation: processes: create: @@ -512,6 +521,7 @@ es: hidden_comments: Comentarios ocultos hidden_debates: Debates ocultos hidden_proposals: Propuestas ocultas + hidden_budget_investments: Proyectos de gasto ocultos hidden_proposal_notifications: Notificationes de propuesta ocultas hidden_users: Usuarios bloqueados administrators: Administradores diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 5ea78fcd5..afad3067c 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -15,6 +15,13 @@ namespace :admin do end end + resources :hidden_budget_investments, only: :index do + member do + put :restore + put :confirm_hide + end + end + resources :debates, only: :index do member do put :restore From c64e93867ae31d939a4a6a8ec2f5408413c23fb2 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 18 Jun 2018 13:10:58 -0400 Subject: [PATCH 18/85] Allow moderators to moderate investments --- app/helpers/admin_helper.rb | 18 +++- app/models/budget/investment.rb | 2 + app/views/moderation/_menu.html.erb | 9 ++ .../budgets/investments/index.html.erb | 82 +++++++++++++++++++ config/locales/en/moderation.yml | 20 +++++ config/locales/es/moderation.yml | 20 +++++ 6 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 app/views/moderation/budgets/investments/index.html.erb diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 1b6783bfa..cf4a74f33 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -1,15 +1,27 @@ module AdminHelper def side_menu - render "/#{namespace}/menu" + if namespace == 'moderation/budgets' + render "/moderation/menu" + else + render "/#{namespace}/menu" + end end def namespaced_root_path - "/#{namespace}" + if namespace == 'moderation/budgets' + "/moderation" + else + "/#{namespace}" + end end def namespaced_header_title - t("#{namespace}.header.title") + if namespace == 'moderation/budgets' + t("moderation.header.title") + else + t("#{namespace}.header.title") + end end def menu_moderated_content? diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 292200f6a..041b1327b 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -78,6 +78,8 @@ class Budget scope :winners, -> { selected.compatible.where(winner: true) } scope :unselected, -> { not_unfeasible.where(selected: false) } scope :last_week, -> { where("created_at >= ?", 7.days.ago)} + scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } + scope :sort_by_created_at, -> { reorder(created_at: :desc) } scope :by_budget, ->(budget) { where(budget: budget) } scope :by_group, ->(group_id) { where(group_id: group_id) } diff --git a/app/views/moderation/_menu.html.erb b/app/views/moderation/_menu.html.erb index 8d7abb85d..0a34adb8b 100644 --- a/app/views/moderation/_menu.html.erb +++ b/app/views/moderation/_menu.html.erb @@ -29,6 +29,15 @@ <% end %> + <% if feature?(:budgets) %> +
  • > + <%= link_to moderation_budget_investments_path do %> + + <%= t("moderation.menu.flagged_investments") %> + <% end %> +
  • + <% end %> +
  • > <%= link_to moderation_comments_path do %> diff --git a/app/views/moderation/budgets/investments/index.html.erb b/app/views/moderation/budgets/investments/index.html.erb new file mode 100644 index 000000000..51f9c47ca --- /dev/null +++ b/app/views/moderation/budgets/investments/index.html.erb @@ -0,0 +1,82 @@ +

    <%= t("moderation.budget_investments.index.title") %>

    + +<%= render "shared/filter_subnav", i18n_namespace: "moderation.budget_investments.index" %> + +
    +

    <%= page_entries_info @budget_investments %>

    +
    +
    + <%= t("moderation.budget_investments.index.order") %> + <%= render "shared/order_selector", i18n_namespace: "moderation.budget_investments.index" %> +
    +
    +
    + +<%= form_tag moderate_moderation_budget_investments_path(request.query_parameters), method: :put do %> +

    + <%= t("shared.check") %>: + <%= link_to t("shared.check_all"), "#", data: { check_all: "budget_investment_ids[]" } %> + | + <%= link_to t("shared.check_none"), "#", data: { check_none: "budget_investment_ids[]" } %> +

    + + + + + + + <% @budget_investments.each do |investment| %> + + + + + <% end %> +
    + <%= t("moderation.budget_investments.index.headers.budget_investment") %> + + <%= t("moderation.budget_investments.index.headers.moderate") %> +
    + <%= link_to investment.title, admin_budget_budget_investment_path( + budget_id: investment.budget_id, + id: investment.id + ), target: "_blank" %> +
    + <%= l investment.updated_at.to_date %> +  •  + <%= investment.flags_count %> +  •  + <%= investment.author.username %> +
    +
    + <%= investment.description %> +
    +
    + <%= check_box_tag "budget_investment_ids[]", investment.id, nil, id: "#{dom_id(investment)}_check" %> +
    + + <%= submit_tag t("moderation.budget_investments.index.block_authors"), + name: "block_authors", + class: "button hollow alert", + data: { + confirm: t("moderation.budget_investments.index.confirm") + } %> + +
    + <%= submit_tag t("moderation.budget_investments.index.hide_budget_investments"), + name: "hide_budget_investments", + class: "button hollow alert", + data: { + confirm: t("moderation.budget_investments.index.confirm") + } %> + + <%= submit_tag t("moderation.budget_investments.index.ignore_flags"), + name: "ignore_flags", + class: "button hollow", + data: { + confirm: t("moderation.budget_investments.index.confirm") + } %> +
    + + <%= paginate @budget_investments %> + +<% end %> diff --git a/config/locales/en/moderation.yml b/config/locales/en/moderation.yml index 5ed2f69bb..623ec0f92 100644 --- a/config/locales/en/moderation.yml +++ b/config/locales/en/moderation.yml @@ -46,6 +46,7 @@ en: menu: flagged_comments: Comments flagged_debates: Debates + flagged_investments: Budget investments proposals: Proposals proposal_notifications: Proposals notifications users: Block users @@ -68,6 +69,25 @@ en: created_at: Most recent flags: Most flagged title: Proposals + budget_investments: + index: + block_authors: Block authors + confirm: Are you sure? + filter: Filter + filters: + all: All + pending_flag_review: Pending + with_ignored_flag: Marked as viewed + headers: + moderate: Moderate + budget_investment: Budget investment + hide_budget_investments: Hide budget investments + ignore_flags: Mark as viewed + order: Order by + orders: + created_at: Most recent + flags: Most flagged + title: Budget investments proposal_notifications: index: block_authors: Block authors diff --git a/config/locales/es/moderation.yml b/config/locales/es/moderation.yml index c51013aee..a1caac77c 100644 --- a/config/locales/es/moderation.yml +++ b/config/locales/es/moderation.yml @@ -46,6 +46,7 @@ es: menu: flagged_comments: Comentarios flagged_debates: Debates + flagged_investments: Proyectos de gasto proposals: Propuestas proposal_notifications: Notificaciones de propuestas users: Bloquear usuarios @@ -68,6 +69,25 @@ es: created_at: Más recientes flags: Más denunciadas title: Propuestas + budget_investments: + index: + block_authors: Bloquear autores + confirm: '¿Estás seguro?' + filter: Filtro + filters: + all: Todos + pending_flag_review: Pendientes de revisión + with_ignored_flag: Marcadas como revisadas + headers: + moderate: Moderar + budget_investment: Proyecto de gasto + hide_budget_investments: Ocultar proyectos de gasto + ignore_flags: Marcar como revisadas + order: Ordenar por + orders: + created_at: Más recientes + flags: Más denunciadas + title: Proyectos de gasto proposal_notifications: index: block_authors: Bloquear autores From 018de5a9f9298ab2114bd9f888b68c6ed01b78bd Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 19 Jun 2018 00:34:51 -0400 Subject: [PATCH 19/85] Add specs for investments moderation --- spec/factories.rb | 18 ++ .../admin/hidden_budget_investments_spec.rb | 108 ++++++++ spec/features/budgets/investments_spec.rb | 65 +++++ .../moderation/budget_investments_spec.rb | 246 ++++++++++++++++++ 4 files changed, 437 insertions(+) create mode 100644 spec/features/admin/hidden_budget_investments_spec.rb create mode 100644 spec/features/moderation/budget_investments_spec.rb diff --git a/spec/factories.rb b/spec/factories.rb index 77deec79a..739078ec7 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -362,6 +362,24 @@ FactoryBot.define do feasibility "feasible" valuation_finished true end + + trait :hidden do + hidden_at Time.current + end + + trait :with_ignored_flag do + ignored_flag_at Time.current + end + + trait :flagged do + after :create do |investment| + Flag.flag(create(:user), investment) + end + end + + trait :with_confirmed_hide do + confirmed_hide_at Time.current + end end factory :budget_phase, class: 'Budget::Phase' do diff --git a/spec/features/admin/hidden_budget_investments_spec.rb b/spec/features/admin/hidden_budget_investments_spec.rb new file mode 100644 index 000000000..2b001830b --- /dev/null +++ b/spec/features/admin/hidden_budget_investments_spec.rb @@ -0,0 +1,108 @@ +require 'rails_helper' + +feature 'Admin hidden budget investments' do + + let(:budget) { create(:budget) } + let(:group) { create(:budget_group, name: 'Music', budget: budget) } + let(:heading) { create(:budget_heading, name: 'Black metal', price: 666666, group: group) } + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'Disabled with a feature flag' do + Setting['feature.budgets'] = nil + + expect{ visit admin_hidden_budget_investments_path }.to raise_exception(FeatureFlags::FeatureDisabled) + + Setting['feature.budgets'] = true + end + + scenario 'List shows all relevant info' do + investment = create(:budget_investment, :hidden, heading: heading) + + visit admin_hidden_budget_investments_path + + expect(page).to have_content(investment.title) + expect(page).to have_content(investment.description) + end + + scenario 'Restore' do + investment = create(:budget_investment, :hidden, heading: heading) + + visit admin_hidden_budget_investments_path + + click_link 'Restore' + + expect(page).not_to have_content(investment.title) + + investment.reload + + expect(investment).to be_ignored_flag + end + + scenario 'Confirm hide' do + investment = create(:budget_investment, :hidden, heading: heading) + visit admin_hidden_budget_investments_path + + click_link('Pending') + expect(page).to have_content(investment.title) + + click_link 'Confirm moderation' + + expect(page).not_to have_content(investment.title) + + click_link('Confirmed') + expect(page).to have_content(investment.title) + + expect(investment.reload).to be_confirmed_hide + end + + scenario "Current filter is properly highlighted" do + visit admin_hidden_budget_investments_path + expect(page).not_to have_link('All') + expect(page).to have_link('Pending') + expect(page).to have_link('Confirmed') + + visit admin_hidden_budget_investments_path(filter: 'without_confirmed_hide') + expect(page).to have_link('All') + expect(page).to have_link('Confirmed') + expect(page).not_to have_link('Pending') + + visit admin_hidden_budget_investments_path(filter: 'with_confirmed_hide') + expect(page).to have_link('All') + expect(page).to have_link('Pending') + expect(page).not_to have_link('Confirmed') + end + + scenario 'Filtering investments' do + create(:budget_investment, :hidden, heading: heading, title: 'Unconfirmed investment') + create(:budget_investment, :hidden, :with_confirmed_hide, heading: heading, title: 'Confirmed investment') + + visit admin_hidden_budget_investments_path(filter: 'without_confirmed_hide') + expect(page).to have_content('Unconfirmed investment') + expect(page).not_to have_content('Confirmed investment') + + visit admin_hidden_budget_investments_path(filter: 'all') + expect(page).to have_content('Unconfirmed investment') + expect(page).to have_content('Confirmed investment') + + visit admin_hidden_budget_investments_path(filter: 'with_confirmed_hide') + expect(page).not_to have_content('Unconfirmed investment') + expect(page).to have_content('Confirmed investment') + end + + scenario "Action links remember the pagination setting and the filter" do + per_page = Kaminari.config.default_per_page + (per_page + 2).times { create(:budget_investment, :hidden, :with_confirmed_hide, heading: heading) } + + visit admin_hidden_budget_investments_path(filter: 'with_confirmed_hide', page: 2) + + click_on('Restore', match: :first, exact: true) + + expect(current_url).to include('filter=with_confirmed_hide') + expect(current_url).to include('page=2') + end + +end diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 1b0f7f31f..d3687a84f 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -1567,4 +1567,69 @@ feature 'Budget Investments' do end end + + scenario 'Flagging an investment as innapropriate', :js do + user = create(:user) + investment = create(:budget_investment, heading: heading) + + login_as(user) + + visit budget_investment_path(budget, investment) + + within "#budget_investment_#{investment.id}" do + find("#flag-expand-investment-#{investment.id}").click + find("#flag-investment-#{investment.id}").click + + expect(page).to have_css("#unflag-expand-investment-#{investment.id}") + end + + expect(Flag.flagged?(user, investment)).to be + end + + scenario 'Unflagging an investment', :js do + user = create(:user) + investment = create(:budget_investment, heading: heading) + Flag.flag(user, investment) + + login_as(user) + + visit budget_investment_path(budget, investment) + + within "#budget_investment_#{investment.id}" do + find("#unflag-expand-investment-#{investment.id}").click + find("#unflag-investment-#{investment.id}").click + + expect(page).to have_css("#flag-expand-investment-#{investment.id}") + end + + expect(Flag.flagged?(user, investment)).not_to be + end + + scenario 'Flagging an investment updates the DOM properly', :js do + user = create(:user) + investment = create(:budget_investment, heading: heading) + + login_as(user) + + visit budget_investment_path(budget, investment) + + within "#budget_investment_#{investment.id}" do + find("#flag-expand-investment-#{investment.id}").click + find("#flag-investment-#{investment.id}").click + + expect(page).to have_css("#unflag-expand-investment-#{investment.id}") + end + + expect(Flag.flagged?(user, investment)).to be + + within "#budget_investment_#{investment.id}" do + find("#unflag-expand-investment-#{investment.id}").click + find("#unflag-investment-#{investment.id}").click + + expect(page).to have_css("#flag-expand-investment-#{investment.id}") + end + + expect(Flag.flagged?(user, investment)).not_to be + end + end diff --git a/spec/features/moderation/budget_investments_spec.rb b/spec/features/moderation/budget_investments_spec.rb new file mode 100644 index 000000000..7cb4f5020 --- /dev/null +++ b/spec/features/moderation/budget_investments_spec.rb @@ -0,0 +1,246 @@ +require 'rails_helper' + +feature 'Moderate budget investments' do + + let(:budget) { create(:budget) } + let(:group) { create(:budget_group, name: 'Culture', budget: budget) } + let(:heading) { create(:budget_heading, name: 'More libraries', price: 666666, group: group) } + + background do + @mod = create(:moderator) + @investment = create(:budget_investment, heading: heading, author: create(:user)) + end + + scenario 'Disabled with a feature flag' do + Setting['feature.budgets'] = nil + login_as(@mod.user) + + expect{ visit moderation_budget_investments_path }.to raise_exception(FeatureFlags::FeatureDisabled) + + Setting['feature.budgets'] = true + end + + scenario 'Hiding an investment', :js do + login_as(@mod.user) + visit budget_investment_path(budget, @investment) + + accept_confirm { click_link 'Hide' } + + expect(page).to have_css('.faded', count: 2) + + visit budget_investments_path(budget.id, heading_id: heading.id) + + expect(page).not_to have_content(@investment.title) + end + + scenario "Hiding an investment's author", :js do + login_as(@mod.user) + visit budget_investment_path(budget, @investment) + + accept_confirm { click_link 'Hide author' } + + expect(page).to have_current_path(debates_path) + + visit budget_investments_path(budget.id, heading_id: heading.id) + + expect(page).not_to have_content(@investment.title) + end + + scenario 'Can not hide own investment' do + @investment.update(author: @mod.user) + login_as(@mod.user) + + visit budget_investment_path(budget, @investment) + + within "#budget_investment_#{@investment.id}" do + expect(page).not_to have_link('Hide') + expect(page).not_to have_link('Hide author') + end + end + + feature '/moderation/ screen' do + + background do + login_as(@mod.user) + end + + feature 'moderate in bulk' do + feature 'When an investment has been selected for moderation' do + + background do + visit moderation_budget_investments_path + + within('.menu.simple') do + click_link 'All' + end + + within("#investment_#{@investment.id}") do + check "budget_investment_#{@investment.id}_check" + end + + expect(page).not_to have_css("investment#{@investment.id}") + end + + scenario 'Hide the investment' do + click_button 'Hide budget investments' + expect(page).not_to have_css("investment_#{@investment.id}") + + @investment.reload + + expect(@investment.author).not_to be_hidden + end + + scenario 'Block the author' do + click_button 'Block authors' + expect(page).not_to have_css("investment_#{@investment.id}") + + @investment.reload + + expect(@investment.author).to be_hidden + end + + scenario 'Ignore the investment' do + click_button 'Mark as viewed' + expect(page).not_to have_css("investment_#{@investment.id}") + + @investment.reload + + expect(@investment).to be_ignored_flag + expect(@investment).not_to be_hidden + expect(@investment.author).not_to be_hidden + end + end + + scenario 'select all/none', :js do + create_list(:budget_investment, 2, heading: heading, author: create(:user)) + + visit moderation_budget_investments_path + + within('.js-check') { click_on 'All' } + + expect(all('input[type=checkbox]')).to all(be_checked) + + within('.js-check') { click_on 'None' } + + all('input[type=checkbox]').each do |checkbox| + expect(checkbox).not_to be_checked + end + end + + scenario 'remembering page, filter and order' do + create_list(:budget_investment, 52, heading: heading, author: create(:user)) + + visit moderation_budget_investments_path(filter: 'all', page: '2', order: 'created_at') + + click_button 'Mark as viewed' + + expect(page).to have_selector('.js-order-selector[data-order="created_at"]') + + expect(current_url).to include('filter=all') + expect(current_url).to include('page=2') + expect(current_url).to include('order=created_at') + end + end + + scenario 'Current filter is properly highlighted' do + visit moderation_budget_investments_path + + expect(page).not_to have_link('Pending') + expect(page).to have_link('All') + expect(page).to have_link('Marked as viewed') + + visit moderation_budget_investments_path(filter: 'all') + + within('.menu.simple') do + expect(page).not_to have_link('All') + expect(page).to have_link('Pending') + expect(page).to have_link('Marked as viewed') + end + + visit moderation_budget_investments_path(filter: 'pending_flag_review') + + within('.menu.simple') do + expect(page).to have_link('All') + expect(page).not_to have_link('Pending') + expect(page).to have_link('Marked as viewed') + end + + visit moderation_budget_investments_path(filter: 'with_ignored_flag') + + within('.menu.simple') do + expect(page).to have_link('All') + expect(page).to have_link('Pending') + expect(page).not_to have_link('Marked as viewed') + end + end + + scenario 'Filtering investments' do + create(:budget_investment, heading: heading, title: 'Books investment') + create(:budget_investment, :flagged, heading: heading, title: 'Non-selected investment') + create(:budget_investment, :hidden, heading: heading, title: 'Hidden investment') + create(:budget_investment, :flagged, :with_ignored_flag, heading: heading, title: 'Ignored investment') + + visit moderation_budget_investments_path(filter: 'all') + + expect(page).to have_content('Books investment') + expect(page).to have_content('Non-selected investment') + expect(page).not_to have_content('Hidden investment') + expect(page).to have_content('Ignored investment') + + visit moderation_budget_investments_path(filter: 'pending_flag_review') + + expect(page).not_to have_content('Books investment') + expect(page).to have_content('Non-selected investment') + expect(page).not_to have_content('Hidden investment') + expect(page).not_to have_content('Ignored investment') + + visit moderation_budget_investments_path(filter: 'with_ignored_flag') + + expect(page).not_to have_content('Books investment') + expect(page).not_to have_content('Non-selected investment') + expect(page).not_to have_content('Hidden investment') + expect(page).to have_content('Ignored investment') + end + + scenario 'sorting investments' do + flagged_investment = create(:budget_investment, + heading: heading, + title: 'Flagged investment', + created_at: Time.current - 1.day, + flags_count: 5 + ) + + flagged_new_investment = create(:budget_investment, + heading: heading, + title: 'Flagged new investment', + created_at: Time.current - 12.hours, + flags_count: 3 + ) + + latest_investment = create(:budget_investment, + heading: heading, + title: 'Latest investment', + created_at: Time.current + ) + + visit moderation_budget_investments_path(order: 'created_at') + + expect(flagged_new_investment.title).to appear_before(flagged_investment.title) + + visit moderation_budget_investments_path(order: 'flags') + + expect(flagged_investment.title).to appear_before(flagged_new_investment.title) + + visit moderation_budget_investments_path(filter: 'all', order: 'created_at') + + expect(latest_investment.title).to appear_before(flagged_new_investment.title) + expect(flagged_new_investment.title).to appear_before(flagged_investment.title) + + visit moderation_budget_investments_path(filter: 'all', order: 'flags') + + expect(flagged_investment.title).to appear_before(flagged_new_investment.title) + expect(flagged_new_investment.title).to appear_before(latest_investment.title) + end + end + +end From 1b370321251b6160f4eb747f7e0bc7d8f90a0512 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 19 Jun 2018 01:25:33 -0400 Subject: [PATCH 20/85] Assume investments moderation I18n keys are used --- config/i18n-tasks.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index a79e521bf..a0fb7110e 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -135,6 +135,7 @@ ignore_unused: - 'admin.spending_proposals.index.filter*' - 'admin.organizations.index.filter*' - 'admin.hidden_users.index.filter*' + - 'admin.hidden_budget_investments.index.filter*' - 'admin.activity.show.filter*' - 'admin.legislation.processes.index.filter*' - 'admin.legislation.processes.*.submit_button' @@ -152,6 +153,8 @@ ignore_unused: - 'moderation.proposals.index.order*' - 'moderation.debates.index.filter*' - 'moderation.debates.index.order*' + - 'moderation.budget_investments.index.filter*' + - 'moderation.budget_investments.index.order*' - 'moderation.proposal_notifications.index.filter*' - 'moderation.proposal_notifications.index.order*' - 'valuation.spending_proposals.index.filter*' From 7f701062996bc4325c33623c1707a62c4c6f7454 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 19 Jun 2018 11:47:31 -0400 Subject: [PATCH 21/85] Fix page entries information positioning for investments moderation --- .../moderation/budgets/investments/index.html.erb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/views/moderation/budgets/investments/index.html.erb b/app/views/moderation/budgets/investments/index.html.erb index 51f9c47ca..3335ec5cd 100644 --- a/app/views/moderation/budgets/investments/index.html.erb +++ b/app/views/moderation/budgets/investments/index.html.erb @@ -2,14 +2,10 @@ <%= render "shared/filter_subnav", i18n_namespace: "moderation.budget_investments.index" %> -
    -

    <%= page_entries_info @budget_investments %>

    -
    -
    - <%= t("moderation.budget_investments.index.order") %> - <%= render "shared/order_selector", i18n_namespace: "moderation.budget_investments.index" %> -
    -
    +

    <%= page_entries_info @budget_investments %>

    +
    + <%= t("moderation.budget_investments.index.order") %> + <%= render "shared/order_selector", i18n_namespace: "moderation.budget_investments.index" %>
    <%= form_tag moderate_moderation_budget_investments_path(request.query_parameters), method: :put do %> From f063391e41892a2fba26ea5a698661cdfb039a42 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 19 Jun 2018 11:58:32 -0400 Subject: [PATCH 22/85] Add missing `thead` & `tbody` tags on investments moderation index --- .../budgets/investments/index.html.erb | 75 +++++++++---------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/app/views/moderation/budgets/investments/index.html.erb b/app/views/moderation/budgets/investments/index.html.erb index 3335ec5cd..d9c636d63 100644 --- a/app/views/moderation/budgets/investments/index.html.erb +++ b/app/views/moderation/budgets/investments/index.html.erb @@ -9,7 +9,7 @@
    <%= form_tag moderate_moderation_budget_investments_path(request.query_parameters), method: :put do %> -

    +

    <%= t("shared.check") %>: <%= link_to t("shared.check_all"), "#", data: { check_all: "budget_investment_ids[]" } %> | @@ -17,60 +17,55 @@

    - - - - - <% @budget_investments.each do |investment| %> - - - + + + + - <% end %> + + + + <% @budget_investments.each do |investment| %> + + + + + <% end %> +
    - <%= t("moderation.budget_investments.index.headers.budget_investment") %> - - <%= t("moderation.budget_investments.index.headers.moderate") %> -
    - <%= link_to investment.title, admin_budget_budget_investment_path( - budget_id: investment.budget_id, - id: investment.id - ), target: "_blank" %> -
    - <%= l investment.updated_at.to_date %> -  •  - <%= investment.flags_count %> -  •  - <%= investment.author.username %> -
    -
    - <%= investment.description %> -
    -
    - <%= check_box_tag "budget_investment_ids[]", investment.id, nil, id: "#{dom_id(investment)}_check" %> -
    <%= t("moderation.budget_investments.index.headers.budget_investment") %><%= t("moderation.budget_investments.index.headers.moderate") %>
    + <%= link_to investment.title, admin_budget_budget_investment_path( + budget_id: investment.budget_id, + id: investment.id + ), target: "_blank" %> +
    + <%= l investment.updated_at.to_date %> +  •  + <%= investment.flags_count %> +  •  + <%= investment.author.username %> +
    +
    + <%= investment.description %> +
    +
    + <%= check_box_tag "budget_investment_ids[]", investment.id, nil, id: "#{dom_id(investment)}_check" %> +
    <%= submit_tag t("moderation.budget_investments.index.block_authors"), name: "block_authors", class: "button hollow alert", - data: { - confirm: t("moderation.budget_investments.index.confirm") - } %> + data: { confirm: t("moderation.budget_investments.index.confirm") } %>
    <%= submit_tag t("moderation.budget_investments.index.hide_budget_investments"), name: "hide_budget_investments", class: "button hollow alert", - data: { - confirm: t("moderation.budget_investments.index.confirm") - } %> + data: { confirm: t("moderation.budget_investments.index.confirm") } %> <%= submit_tag t("moderation.budget_investments.index.ignore_flags"), name: "ignore_flags", class: "button hollow", - data: { - confirm: t("moderation.budget_investments.index.confirm") - } %> + data: { confirm: t("moderation.budget_investments.index.confirm") } %>
    <%= paginate @budget_investments %> From c18479e3acefe21b766362ad65f0a27458937a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Fuentes?= Date: Wed, 18 Jul 2018 13:40:06 +0200 Subject: [PATCH 23/85] Add translations management pages In the admin section of the application, a new page has been added so that the admins are able to manage the selected texts for translate. The texts have been divided in different "sections", depending on the nature of themselves (budgets, polls, proposals, management, etc.). Each section has become a tab with a form associated to edit all the texts for her. When a language is added, it's added for ALL the texts in the application. That means that, if an admin adds french for debates, the french form will appear for the rest of the texts. That doesn't mean that they need to fill all the texts, only that the languages work for all of them instead of individually. --- .../information_texts_controller.rb | 41 +++++++++++++++++++ app/helpers/site_customization_helper.rb | 5 +++ app/models/i18n_content_translation.rb | 5 +++ app/views/admin/_menu.html.erb | 4 ++ .../information_texts/_debates.html.erb | 3 ++ .../information_texts/_emails.html.erb | 3 ++ .../information_texts/_form.html.erb | 15 +++++++ .../information_texts/_form_field.html.erb | 9 ++++ .../_globalize_locales.html.erb | 27 ++++++++++++ .../information_texts/_management.html.erb | 3 ++ .../_more_information.html.erb | 3 ++ .../_participatory_budgets.html.erb | 3 ++ .../information_texts/_polls.html.erb | 3 ++ .../information_texts/_proposals.html.erb | 3 ++ .../information_texts/_tabs.html.erb | 23 +++++++++++ .../information_texts/index.html.erb | 33 +++++++++++++++ config/routes/admin.rb | 3 ++ 17 files changed, 186 insertions(+) create mode 100644 app/controllers/admin/site_customization/information_texts_controller.rb create mode 100644 app/helpers/site_customization_helper.rb create mode 100644 app/models/i18n_content_translation.rb create mode 100644 app/views/admin/site_customization/information_texts/_debates.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_emails.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_form.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_form_field.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_globalize_locales.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_management.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_more_information.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_polls.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_proposals.html.erb create mode 100644 app/views/admin/site_customization/information_texts/_tabs.html.erb create mode 100644 app/views/admin/site_customization/information_texts/index.html.erb diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb new file mode 100644 index 000000000..2049ab75d --- /dev/null +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -0,0 +1,41 @@ +class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomization::BaseController + include Translatable + + def index + @contents = I18nContent.all + end + + def update + content_params.each do |content| + text = I18nContent.find(content[:id]) + text.update(content[:values].slice(*translation_params(content[:values]))) + end + redirect_to admin_site_customization_information_texts_path + end + + private + + def i18n_content_params + attributes = [:key, :value] + params.require(:information_texts).permit(*attributes, translation_params(params[:information_texts])) + end + + def resource_model + I18nContent + end + + def resource + resource_model.find(content_params[:id]) + end + + def content_params + params.require(:contents).values + end + + def delete_translations + languages_to_delete = params[:delete_translations].select { |k, v| params[:delete_translations][k] == "1" }.keys + languages_to_delete.each do |locale| + I18nContentTranslation.destroy_all(locale: locale) + end + end +end diff --git a/app/helpers/site_customization_helper.rb b/app/helpers/site_customization_helper.rb new file mode 100644 index 000000000..52fb3a940 --- /dev/null +++ b/app/helpers/site_customization_helper.rb @@ -0,0 +1,5 @@ +module SiteCustomizationHelper + def site_customization_display_translation?(locale) + I18nContentTranslation.existing_languages.include?(neutral_locale(locale)) ? "" : "display: none" + end +end diff --git a/app/models/i18n_content_translation.rb b/app/models/i18n_content_translation.rb new file mode 100644 index 000000000..76447d83e --- /dev/null +++ b/app/models/i18n_content_translation.rb @@ -0,0 +1,5 @@ +class I18nContentTranslation < ActiveRecord::Base + def self.existing_languages + self.select(:locale).uniq.map{ |l| l.locale.to_sym }.to_a + end +end diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index ffec03232..d6c31a892 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -237,6 +237,10 @@
  • > <%= link_to t("admin.menu.site_customization.content_blocks"), admin_site_customization_content_blocks_path%>
  • + +
  • > + <%= link_to t("admin.menu.site_customization.information_texts"), admin_site_customization_information_texts_path%> +
  • diff --git a/app/views/admin/site_customization/information_texts/_debates.html.erb b/app/views/admin/site_customization/information_texts/_debates.html.erb new file mode 100644 index 000000000..25130608f --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_debates.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.debates] %> diff --git a/app/views/admin/site_customization/information_texts/_emails.html.erb b/app/views/admin/site_customization/information_texts/_emails.html.erb new file mode 100644 index 000000000..01836c341 --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_emails.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.emails] %> diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/views/admin/site_customization/information_texts/_form.html.erb new file mode 100644 index 000000000..54039694d --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_form.html.erb @@ -0,0 +1,15 @@ +<%= form_tag admin_site_customization_information_texts_path do %> + <% I18n.available_locales.each do |l| %> + <%= hidden_field_tag "delete_translations[#{l}]", 0 %> + <% end %> + <% contents.each do |group| %> + <% group.each do |content| %> + <%= t(content[:key]) %> + <% content.globalize_locales.each do |locale| %> + <%= render 'form_field', content: content, locale: locale %> + <% end %> + + <% end %> + <% end %> + <%= submit_tag "Save", class: "button" %> +<% end %> diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb new file mode 100644 index 000000000..5dbe732df --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -0,0 +1,9 @@ +<% globalize(locale) do %> + <%= hidden_field_tag "contents[content_#{content.id}][id]", content.id %> + <%= text_area_tag "contents[content_#{content.id}]values[value_#{locale}]", + content.send("value_#{locale}"), + {rows: 5, + class: "js-globalize-attribute", + style: display_translation?(locale), + data: { locale: locale }}%> +<% end %> diff --git a/app/views/admin/site_customization/information_texts/_globalize_locales.html.erb b/app/views/admin/site_customization/information_texts/_globalize_locales.html.erb new file mode 100644 index 000000000..9e90283cd --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_globalize_locales.html.erb @@ -0,0 +1,27 @@ +<% I18n.available_locales.each do |locale| %> + <%= link_to t("admin.milestones.form.remove_language"), "#", + id: "delete-#{neutral_locale(locale)}", + style: show_delete?(locale), + class: 'float-right delete js-delete-language', + data: { locale: neutral_locale(locale) } %> + +<% end %> + +
      + <% I18n.available_locales.each do |locale| %> +
    • + <%= link_to name_for_locale(locale), "#", + style: site_customization_display_translation?(locale), + class: "js-globalize-locale-link #{highlight_current?(locale)}", + data: { locale: neutral_locale(locale) }, + remote: true %> +
    • + <% end %> +
    + +
    + <%= select_tag :translation_locale, + options_for_locale_select, + prompt: t("admin.milestones.form.add_language"), + class: "js-globalize-locale" %> +
    diff --git a/app/views/admin/site_customization/information_texts/_management.html.erb b/app/views/admin/site_customization/information_texts/_management.html.erb new file mode 100644 index 000000000..2bc6c226e --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_management.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.management, I18nContent.guides] %> diff --git a/app/views/admin/site_customization/information_texts/_more_information.html.erb b/app/views/admin/site_customization/information_texts/_more_information.html.erb new file mode 100644 index 000000000..14a8d788f --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_more_information.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.devise_locales, I18nContent.devise_views, I18nContent.layouts, I18nContent.legislation] %> diff --git a/app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb b/app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb new file mode 100644 index 000000000..4ef7e1c15 --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.budgets] %> diff --git a/app/views/admin/site_customization/information_texts/_polls.html.erb b/app/views/admin/site_customization/information_texts/_polls.html.erb new file mode 100644 index 000000000..9798bd6ef --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_polls.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.polls] %> diff --git a/app/views/admin/site_customization/information_texts/_proposals.html.erb b/app/views/admin/site_customization/information_texts/_proposals.html.erb new file mode 100644 index 000000000..c1e58679d --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_proposals.html.erb @@ -0,0 +1,3 @@ +<%= render "globalize_locales" %> + +<%= render "form", contents: [I18nContent.community, I18nContent.proposals] %> diff --git a/app/views/admin/site_customization/information_texts/_tabs.html.erb b/app/views/admin/site_customization/information_texts/_tabs.html.erb new file mode 100644 index 000000000..7eabb3246 --- /dev/null +++ b/app/views/admin/site_customization/information_texts/_tabs.html.erb @@ -0,0 +1,23 @@ +
      +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.debates"), "#tab-debates" %> +
    • +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.proposals"), "#tab-proposals" %> +
    • +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.polls"), "#tab-polls" %> +
    • +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.participatory_budgets"), "#tab-participatory-budgets" %> +
    • +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.more_information"), "#tab-more-information" %> +
    • +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.emails"), "#tab-emails" %> +
    • +
    • + <%= link_to t("admin.menu.site_customization.information_texts_menu.management"), "#tab-management" %> +
    • +
    diff --git a/app/views/admin/site_customization/information_texts/index.html.erb b/app/views/admin/site_customization/information_texts/index.html.erb new file mode 100644 index 000000000..78d427f66 --- /dev/null +++ b/app/views/admin/site_customization/information_texts/index.html.erb @@ -0,0 +1,33 @@ +

    <%= t("admin.menu.site_customization.information_texts") %>

    + +
    + <%= render 'tabs' %> + + + + + + + + + + + + + + +
    diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 31138e48c..22ac3ae5e 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -200,6 +200,9 @@ namespace :admin do resources :pages, except: [:show] resources :images, only: [:index, :update, :destroy] resources :content_blocks, except: [:show] + resources :information_texts, only: [:index] do + post :update, on: :collection + end end resource :homepage, controller: :homepage, only: [:show] From 6d6dc32c387a3420adf2a9955a7be43c493774fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Fuentes?= Date: Fri, 20 Jul 2018 13:54:52 +0200 Subject: [PATCH 24/85] Complete basic I18n backend and frontend --- .../information_texts_controller.rb | 72 ++++--- app/models/i18n_content.rb | 11 ++ .../information_texts/_debates.html.erb | 3 - .../information_texts/_emails.html.erb | 3 - .../information_texts/_form.html.erb | 3 +- .../information_texts/_form_field.html.erb | 6 +- .../information_texts/_management.html.erb | 3 - .../_more_information.html.erb | 3 - .../_participatory_budgets.html.erb | 3 - .../information_texts/_polls.html.erb | 3 - .../information_texts/_proposals.html.erb | 3 - .../information_texts/_tabs.html.erb | 28 +-- .../information_texts/index.html.erb | 27 +-- app/views/welcome/welcome.html.erb | 2 +- config/initializers/i18n_translation.rb | 25 +++ config/locales/en/i18n_contents.yml | 180 ++++++++++++++++++ config/locales/es/i18n_contents.yml | 180 ++++++++++++++++++ ...115545_create_i18n_content_translations.rb | 17 ++ db/schema.rb | 17 +- 19 files changed, 490 insertions(+), 99 deletions(-) create mode 100644 app/models/i18n_content.rb delete mode 100644 app/views/admin/site_customization/information_texts/_debates.html.erb delete mode 100644 app/views/admin/site_customization/information_texts/_emails.html.erb delete mode 100644 app/views/admin/site_customization/information_texts/_management.html.erb delete mode 100644 app/views/admin/site_customization/information_texts/_more_information.html.erb delete mode 100644 app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb delete mode 100644 app/views/admin/site_customization/information_texts/_polls.html.erb delete mode 100644 app/views/admin/site_customization/information_texts/_proposals.html.erb create mode 100644 config/initializers/i18n_translation.rb create mode 100644 config/locales/en/i18n_contents.yml create mode 100644 config/locales/es/i18n_contents.yml create mode 100644 db/migrate/20180718115545_create_i18n_content_translations.rb diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 2049ab75d..6f2e6777d 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -2,40 +2,62 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz include Translatable def index - @contents = I18nContent.all + existing_keys = {} + @tab = params[:tab] || :debates + I18nContent.begins_with_key(@tab).all. + map{|content| existing_keys[content.key] = content } + @content = {} + I18n.backend.send(:translations)[:en].each do |k,v| + @content[k.to_s] = flat_hash(v).keys.map{|s| existing_keys["#{k.to_s}.#{s}"].nil? ? + I18nContent.new(key: "#{k.to_s}.#{s}") : + existing_keys["#{k.to_s}.#{s}"] } + end + @content = @content[@tab.to_s] + end def update content_params.each do |content| - text = I18nContent.find(content[:id]) - text.update(content[:values].slice(*translation_params(content[:values]))) + value = content[:values].slice(*translation_params(content[:values])) + unless value.empty? + text = I18nContent.by_key(content[:id]).last || I18nContent.create(key: content[:id]) + text.update(value) + text.save + end end redirect_to admin_site_customization_information_texts_path end private - def i18n_content_params - attributes = [:key, :value] - params.require(:information_texts).permit(*attributes, translation_params(params[:information_texts])) - end - - def resource_model - I18nContent - end - - def resource - resource_model.find(content_params[:id]) - end - - def content_params - params.require(:contents).values - end - - def delete_translations - languages_to_delete = params[:delete_translations].select { |k, v| params[:delete_translations][k] == "1" }.keys - languages_to_delete.each do |locale| - I18nContentTranslation.destroy_all(locale: locale) + def i18n_content_params + attributes = [:key, :value] + params.require(:information_texts).permit(*attributes, translation_params(params[:information_texts])) end - end + + def resource_model + I18nContent + end + + def resource + resource_model.find(content_params[:id]) + end + + def content_params + params.require(:contents).values + end + + def delete_translations + languages_to_delete = params[:delete_translations].select { |k, v| params[:delete_translations][k] == "1" }.keys + languages_to_delete.each do |locale| + I18nContentTranslation.destroy_all(locale: locale) + end + end + + def flat_hash(h, f=nil, g={}) + return g.update({ f => h }) unless h.is_a? Hash + h.each { |k, r| flat_hash(r, [f,k].compact.join('.'), g) } + g + end + end diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb new file mode 100644 index 000000000..48192d0ef --- /dev/null +++ b/app/models/i18n_content.rb @@ -0,0 +1,11 @@ +class I18nContent < ActiveRecord::Base + + scope :by_key, -> (key){ where(key: key) } + scope :begins_with_key, -> (key){ where("key LIKE ?", "#{key}?%") } + + validates :key, uniqueness: true + + translates :value, touch: true + globalize_accessors locales: [:en, :es, :fr, :nl, :val, :pt_br] + +end \ No newline at end of file diff --git a/app/views/admin/site_customization/information_texts/_debates.html.erb b/app/views/admin/site_customization/information_texts/_debates.html.erb deleted file mode 100644 index 25130608f..000000000 --- a/app/views/admin/site_customization/information_texts/_debates.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.debates] %> diff --git a/app/views/admin/site_customization/information_texts/_emails.html.erb b/app/views/admin/site_customization/information_texts/_emails.html.erb deleted file mode 100644 index 01836c341..000000000 --- a/app/views/admin/site_customization/information_texts/_emails.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.emails] %> diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/views/admin/site_customization/information_texts/_form.html.erb index 54039694d..d3c0489b7 100644 --- a/app/views/admin/site_customization/information_texts/_form.html.erb +++ b/app/views/admin/site_customization/information_texts/_form.html.erb @@ -1,3 +1,5 @@ +<%= render "globalize_locales" %> + <%= form_tag admin_site_customization_information_texts_path do %> <% I18n.available_locales.each do |l| %> <%= hidden_field_tag "delete_translations[#{l}]", 0 %> @@ -8,7 +10,6 @@ <% content.globalize_locales.each do |locale| %> <%= render 'form_field', content: content, locale: locale %> <% end %> - <% end %> <% end %> <%= submit_tag "Save", class: "button" %> diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index 5dbe732df..f247870f4 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -1,9 +1,9 @@ <% globalize(locale) do %> - <%= hidden_field_tag "contents[content_#{content.id}][id]", content.id %> - <%= text_area_tag "contents[content_#{content.id}]values[value_#{locale}]", + <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> + <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", content.send("value_#{locale}"), {rows: 5, class: "js-globalize-attribute", style: display_translation?(locale), - data: { locale: locale }}%> + data: { locale: locale }} %> <% end %> diff --git a/app/views/admin/site_customization/information_texts/_management.html.erb b/app/views/admin/site_customization/information_texts/_management.html.erb deleted file mode 100644 index 2bc6c226e..000000000 --- a/app/views/admin/site_customization/information_texts/_management.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.management, I18nContent.guides] %> diff --git a/app/views/admin/site_customization/information_texts/_more_information.html.erb b/app/views/admin/site_customization/information_texts/_more_information.html.erb deleted file mode 100644 index 14a8d788f..000000000 --- a/app/views/admin/site_customization/information_texts/_more_information.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.devise_locales, I18nContent.devise_views, I18nContent.layouts, I18nContent.legislation] %> diff --git a/app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb b/app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb deleted file mode 100644 index 4ef7e1c15..000000000 --- a/app/views/admin/site_customization/information_texts/_participatory_budgets.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.budgets] %> diff --git a/app/views/admin/site_customization/information_texts/_polls.html.erb b/app/views/admin/site_customization/information_texts/_polls.html.erb deleted file mode 100644 index 9798bd6ef..000000000 --- a/app/views/admin/site_customization/information_texts/_polls.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.polls] %> diff --git a/app/views/admin/site_customization/information_texts/_proposals.html.erb b/app/views/admin/site_customization/information_texts/_proposals.html.erb deleted file mode 100644 index c1e58679d..000000000 --- a/app/views/admin/site_customization/information_texts/_proposals.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= render "globalize_locales" %> - -<%= render "form", contents: [I18nContent.community, I18nContent.proposals] %> diff --git a/app/views/admin/site_customization/information_texts/_tabs.html.erb b/app/views/admin/site_customization/information_texts/_tabs.html.erb index 7eabb3246..e3ba440c9 100644 --- a/app/views/admin/site_customization/information_texts/_tabs.html.erb +++ b/app/views/admin/site_customization/information_texts/_tabs.html.erb @@ -1,23 +1,7 @@ -
      -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.debates"), "#tab-debates" %> -
    • -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.proposals"), "#tab-proposals" %> -
    • -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.polls"), "#tab-polls" %> -
    • -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.participatory_budgets"), "#tab-participatory-budgets" %> -
    • -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.more_information"), "#tab-more-information" %> -
    • -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.emails"), "#tab-emails" %> -
    • -
    • - <%= link_to t("admin.menu.site_customization.information_texts_menu.management"), "#tab-management" %> -
    • +
        + <% [:debates, :community, :proposals, :polls, :layouts, :emails, :management, :guides, :welcome].each do |tab| %> +
      • "> + <%= link_to t("admin.menu.site_customization.information_texts_menu.#{tab}"), admin_site_customization_information_texts_path(tab: tab) %> +
      • + <% end %>
      diff --git a/app/views/admin/site_customization/information_texts/index.html.erb b/app/views/admin/site_customization/information_texts/index.html.erb index 78d427f66..f41102d97 100644 --- a/app/views/admin/site_customization/information_texts/index.html.erb +++ b/app/views/admin/site_customization/information_texts/index.html.erb @@ -3,31 +3,8 @@
      <%= render 'tabs' %> - diff --git a/app/views/welcome/welcome.html.erb b/app/views/welcome/welcome.html.erb index ec51e225f..abd3c15a0 100644 --- a/app/views/welcome/welcome.html.erb +++ b/app/views/welcome/welcome.html.erb @@ -3,7 +3,7 @@

      <%= t("welcome.welcome.user_permission_info") %>

      - +1
      •  <%= t("welcome.welcome.user_permission_debates") %>
      •  <%= t("welcome.welcome.user_permission_proposal") %>
      • diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb new file mode 100644 index 000000000..0ee8606b6 --- /dev/null +++ b/config/initializers/i18n_translation.rb @@ -0,0 +1,25 @@ +require 'action_view/helpers/tag_helper' +require 'i18n/exceptions' + +module ActionView + # = Action View Translation Helpers + module Helpers + module TranslationHelper + include TagHelper + + def t(key, options = {}) + if translation = I18nContent.by_key(key).last + Globalize.with_locale(locale) do + string = I18nContent.where(key: key).first.value + options.each do |key, value| + string.sub! "%{#{key}}", (value || "%{#{key}}") + end + return string.html_safe + end + end + translate(key, options) + end + + end + end +end diff --git a/config/locales/en/i18n_contents.yml b/config/locales/en/i18n_contents.yml new file mode 100644 index 000000000..9c7409749 --- /dev/null +++ b/config/locales/en/i18n_contents.yml @@ -0,0 +1,180 @@ +en: + budgets: + index: + section_footer: + description: 'Debates section description' + help_text_1: 'Help text 1 for debates section' + help_text_2: 'Help text 2 for debates section' + help_text_3: 'Help text 3 for debates section' + help_text_4: 'Help text 4 for debates section' + community: + topic: + sidebar: + recommendation_one: 'Recommendation 1 when create a topic on a proposal community' + recommendation_two: 'Recommendation 2 when create a topic on a proposal community' + recommendation_three: 'Recommendation 3 when create a topic on a proposal community' + devise: + registrations: + destroyed: 'Message when deleting an account' + devise_views: + mailer: + confirmation_instructions: + title: 'Confirmation email title' + debates: + index: + section_footer: + description: 'Debates section description' + help_text_1: 'Help text 1 for debates section' + help_text_2: 'Help text 2 for debates section' + help_text_3: 'Help text 3 for debates section' + new: + recommendation_one: 'Recommendation 1 when creating debates' + recommendation_two: 'Recommendation 2 when creating debates' + recommendation_three: 'Recommendation 3 when creating debates' + recommendation_four: 'Recommendation 4 when creating debates' + layouts: + footer: + accessibility: 'Accessibility link name' + conditions: 'Conditions link name' + privacy: 'Privary policy link name' + proposals: + index: + section_footer: + description: 'Proposal page description' + help_text_1: 'Help text 1 of proposal page' + help_text_2: 'Help text 2 of proposal page' + help_text_3: 'Help text 3 of proposal page' + new: + form: + submit_button: '"Create proposal" button text' + more_info: '"More information" text in new proposal' + recommendation_one: 'Recommendation 1 in new proposal' + recommendation_two: 'Recommendation 2 in new proposal' + recommendation_three: 'Recommendation 3 in new proposal' + proposal: + reason_for_supports_necessary: 'Supports needed for proposal' + polls: + index: + section_footer: + description: 'Polls description' + help_text_1: 'Help text 1 of polls' + help_text_2: 'Help text 2 of polls' + legislation: + processes: + index: + section_footer: + description: 'Legislation processes description' + help_text_1: 'Help text 1 of legislation processes' + help_text_2: 'Help text 2 of legislation processes' + help_text_3: 'Help text 3 of legislation processes' + management: + print: + proposals_info: 'Printed proposal information' + proposals_note: 'Printed proposal note' + proposals_title: 'Printed proposal title' + budget_investments_info: 'Printed budget investments information' + budgets_investments_note: 'Printed budget investments note' + guides: + title: 'Guides titles' + subtitle: 'Guides subtitle' + budget_investment: + title: 'Budget investments guides title' + feature_1_html: 'Budget investments guides feature 1' + feature_2_html: 'Budget investments guides feature 2' + feature_3_html: 'Budget investments guides feature 3' + feature_4_html: 'Budget investments guides feature 4' + new_button: 'New investment button' + proposal: + title: 'Proposal guides title' + feature_1_html: 'Proposal guides feature 1' + feature_2_html: 'Proposal guides feature 2' + feature_3_html: 'Proposal guides feature 3' + feature_4_html: 'Proposal guides feature 4' + new_button: 'New proposal button' + mailers: + no_reply: 'No reply message' + comment: + hi: 'New comment email greetings' + new_comment_by_html: 'New comment text' + subject: 'New comment subject' + title: 'New comment title' + config: + manage_email_subscriptions: 'Manage email subscriptions' + email_verification: + click_here_to_verify: 'Link name to verify account' + instructions_2_html: 'Instructions to verify account 2' + instructions_html: 'Instructions to verify account' + subject: 'verify account subject' + thanks: 'Thanks' + title: 'Verify account title' + reply: + hi: 'New answer greetings' + new_reply_by_html: 'New answer text' + subject: 'New answer subject' + title: 'New answer title' + unfeasible_spending_proposal: + hi: 'Unfeasible spending proposal greetings' + reconsider_html: 'Unfeasible spending proposal reconsider text' + sincerely: 'Unfeasible spending proposal sincerely' + signatory: 'Unfeasible spending proposal signatory' + sorry: 'Unfeasible spending proposal sorry' + subject: 'Unfeasible spending proposal subject' + unfeasible_html: 'Unfeasible spending proposal text' + budget_investment_unfeasible: + hi: 'Budget investment unfeasible greetings' + reconsider_html: 'Budget investment unfeasible reconsider text' + sincerely: 'Budget investment unfeasible sincerely' + signatory: 'Budget investment unfeasible signatory' + sorry: 'Budget investment unfeasible sorry' + subject: 'Budget investment unfeasible subject' + unfeasible_html: 'Budget investment unfeasible text' + proposal_notification_digest: + info: 'Proposal notification digest information' + title: 'Proposal notification digest title' + share: 'Proposal notification digest share' + comment: 'Proposal notification digest share button' + unsubscribe: 'Proposal notification digest unsubscribe' + unsubscribe_account: 'Proposal notification digest unsubscribe link text' + direct_message_for_receiver: + subject: 'New direct message subject' + reply: 'Reply message subject button text' + unsubscribe: 'Unsubscribe direct messages emails' + unsubscribe_account: 'Unsubscribe direct message emails link text' + direct_message_for_sender: + subject: 'Direct message sender subject' + title_html: 'Direct message sender title' + user_invite: + ignore: 'User invitation ignore' + text: 'User invitation text' + thanks: 'User invitation thanks' + title: 'User invitation title' + button: 'User invitation button' + subject: 'User invitation subject' + budget_investment_created: + subject: 'Budget investment created subject' + title: 'Budget investment created title' + intro_html: 'Budget investment created intro' + text_html: 'Budget investment created text' + follow_html: 'Budget investment created follow' + follow_link: 'Budget investment created follow link' + sincerely: 'Budget investment created sincerely' + signatory: 'Budget investment created signatory' + share: 'Budget investment created share' + budget_investment_selected: + subject: 'Budget investment selected subject' + hi: 'Budget investment selected greetings' + selected_html: 'Budget investment selected text' + share: 'Budget investment selected share' + share_button: 'Budget investment selected share button' + thanks: 'Budget investment selected thanks' + sincerely: 'Budget investment selected sincerely' + signatory: 'Budget investment selected signatory' + budget_investment_unselected: + subject: 'Budget investment unselected subject' + hi: 'Budget investment unselected greetings' + unselected_html: 'Budget investment unselected text' + participate_html: 'Budget investment unselected participate' + participate_url: 'Budget investment unselected participate URL' + thanks: 'Budget investment unselected thanks' + sincerely: 'Budget investment unselected sincerely' + signatory: 'Budget investment unselected signatory' \ No newline at end of file diff --git a/config/locales/es/i18n_contents.yml b/config/locales/es/i18n_contents.yml new file mode 100644 index 000000000..0e1ec82cb --- /dev/null +++ b/config/locales/es/i18n_contents.yml @@ -0,0 +1,180 @@ +es: + budgets: + index: + section_footer: + description: 'Descripción de la sección de debates' + help_text_1: 'Texto de ayuda 1 para la sección de debates' + help_text_2: 'Texto de ayuda 2 para la sección de debates' + help_text_3: 'Texto de ayuda 3 para la sección de debates' + help_text_4: 'Texto de ayuda 4 para la sección de debates' + community: + topic: + sidebar: + recommendation_one: 'Recomendación 1 en la creación de un tema en la comunidad de propuestas' + recommendation_two: 'Recomendación 2 en la creación de un tema en la comunidad de propuestas' + recommendation_three: 'Recomendación 3 en la creación de un tema en la comunidad de propuestas' + devise: + registrations: + destroyed: 'Mensaje al eliminar una cuenta' + devise_views: + mailer: + confirmation_instructions: + title: 'Título del email de confimación' + debates: + index: + section_footer: + description: 'Descripción de la ayuda del índice de debates' + help_text_1: 'Texto de ayuda 1 del índice de debates' + help_text_2: 'Texto de ayuda 2 del índice de debates' + help_text_3: 'Texto de ayuda 3 del índice de debates' + new: + recommendation_one: 'Recomendación 1 en la creación de debates' + recommendation_two: 'Recomendación 2 en la creación de debates' + recommendation_three: 'Recomendación 3 en la creación de debates' + recommendation_four: 'Recomendación 4 en la creación de debates' + layouts: + footer: + accessibility: 'Nombre enlace accesibilidad' + conditions: 'Nombre enlace condiciones de uso' + privacy: 'Nombre enlace política de privacidad' + proposals: + index: + section_footer: + description: 'Descripción de la página de propuestas' + help_text_1: 'Texto de ayuda 1 en la página de propuestas' + help_text_2: 'Texto de ayuda 2 en la página de propuestas' + help_text_3: 'Texto de ayuda 3 en la página de propuestas' + new: + form: + submit_button: 'Texto del botón "Crear propuesta"' + more_info: 'Texto "Más información" de la página de nueva propuesta' + recommendation_one: 'Recomendación 1 de la página de nueva propuesta' + recommendation_two: 'Recomendación 2 de la página de nueva propuesta' + recommendation_three: 'Recomendación 3 de la página de nueva propuesta' + proposal: + reason_for_supports_necessary: 'Número de apoyos necesarios para las propuestas' + polls: + index: + section_footer: + description: 'Descripción de la página de votaciones' + help_text_1: 'Texto de ayuda 1 en la página de votaciones' + help_text_2: 'Texto de ayuda 2 en la página de votaciones' + legislation: + processes: + index: + section_footer: + description: 'Descripción procesos legislativos' + help_text_1: 'Texto ayuda 1 procesos legislativos' + help_text_2: 'Texto ayuda 2 procesos legislativos' + help_text_3: 'Texto ayuda 3 procesos legislativos' + management: + print: + proposals_info: 'Información de propuestas (impresas)' + proposals_note: 'Nota de propuetas (impresas)' + proposals_title: 'Título de propuestas (impresas)' + budget_investments_info: 'Información de proyectos (impresos)' + budgets_investments_note: 'Notas de proyectos (impresos)' + guides: + title: 'Título de las guías' + subtitle: 'Subtítulo de las guías' + budget_investment: + title: 'Título de guías de presupuestos' + feature_1_html: 'Característica 1 de presupuestos' + feature_2_html: 'Característica 2 de presupuestos' + feature_3_html: 'Característica 3 de presupuestos' + feature_4_html: 'Característica 4 de presupuestos' + new_button: 'Botón de nuevo presupuesto' + proposal: + title: 'Título de guías de propuestas' + feature_1_html: 'Característica 1 de propuestas' + feature_2_html: 'Característica 2 de propuestas' + feature_3_html: 'Característica 3 de propuestas' + feature_4_html: 'Característica 4 de propuestas' + new_button: 'Botón de nueva propuesta' + mailers: + no_reply: 'Mensaje de no contestar' + comment: + hi: 'Saludo email nuevo comentario' + new_comment_by_html: 'Texto nuevo comentario' + subject: 'Asunto nuevo comentario' + title: 'Título nuevo comentario' + config: + manage_email_subscriptions: 'Gestionar subscripciones de emails' + email_verification: + click_here_to_verify: 'Nombre enlace para verificar la cuenta' + instructions_2_html: 'Instrucciones para verificar la cuenta 2' + instructions_html: 'Instrucciones para verificar la cuenta' + subject: 'Asunto verificar la cuenta' + thanks: 'Agradecimientos' + title: 'Título email verificación' + reply: + hi: 'Saludo email nueva respuesta' + new_reply_by_html: 'Texto email nueva respuesta' + subject: 'Asunto email nueva respuesta' + title: 'Título email nueva respuesta' + unfeasible_spending_proposal: + hi: 'Saludo email proyecto inviable' + reconsider_html: 'Texto para reconsiderar el proyecto' + sincerely: 'Saludo final' + signatory: 'Firma' + sorry: 'Disculpas' + subject: 'Asunto' + unfeasible_html: 'Texto email inviable' + budget_investment_unfeasible: + hi: 'Saludo email proyecto inviable' + reconsider_html: 'Texto para reconsiderar la proyecto' + sincerely: 'Saludo final' + signatory: 'Firma' + sorry: 'Disculpas' + subject: 'Asunto' + unfeasible_html: 'Texto email inviable' + proposal_notification_digest: + info: 'Información resumen propuestas' + title: 'Título resumen propuestas' + share: 'Texto compartir propuesta' + comment: 'Texto comentar propuesta' + unsubscribe: 'Cancelar subscripción' + unsubscribe_account: 'Texto enlace cancelar subscripción' + direct_message_for_receiver: + subject: 'Asunto nuevo mensaje privado' + reply: 'Texto enlace responder mensaje privado' + unsubscribe: 'Cancelar avisos de mensajes privados' + unsubscribe_account: 'Texto enlace cancelar subscripción' + direct_message_for_sender: + subject: 'Asunto email envío mensaje privado' + title_html: 'Título email envío mensaje privado' + user_invite: + ignore: 'Ignorar correo de invitación' + text: 'Texto email invitación' + thanks: 'Agradecimiento email invitación' + title: 'Título email invitación' + button: 'Botón email invitación' + subject: 'Asunto email invitación' + budget_investment_created: + subject: 'Asunto email proyecto de inversión' + title: 'Título email proyecto de inversión' + intro_html: 'Saludo' + text_html: 'Texto' + follow_html: 'Texto seguir proceso' + follow_link: 'Texto link seguir proceso' + sincerely: 'Saludo final' + signatory: 'Firma' + share: 'Texto compartir' + budget_investment_selected: + subject: 'Asunto' + hi: 'Saludo' + selected_html: 'Texto seleccionado' + share: 'Compartir' + share_button: 'Botón compartir' + thanks: 'Agradecimientos' + sincerely: 'Saludo final' + signatory: 'Firma' + budget_investment_unselected: + subject: 'Asunto' + hi: 'Saludo' + unselected_html: 'Texto no seleccionado' + participate_html: 'Texto seguir participando' + participate_url: 'URL seguir participando' + thanks: 'Agradecimientos' + sincerely: 'Saludo final' + signatory: 'Firma' \ No newline at end of file diff --git a/db/migrate/20180718115545_create_i18n_content_translations.rb b/db/migrate/20180718115545_create_i18n_content_translations.rb new file mode 100644 index 000000000..e472f0622 --- /dev/null +++ b/db/migrate/20180718115545_create_i18n_content_translations.rb @@ -0,0 +1,17 @@ +class CreateI18nContentTranslations < ActiveRecord::Migration + def change + create_table :i18n_contents do |t| + t.string :key + end + + reversible do |dir| + dir.up do + I18nContent.create_translation_table! :value => :text + end + + dir.down do + I18nContent.drop_translation_table! + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 142990d93..388a3ee72 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: 20180711224810) do +ActiveRecord::Schema.define(version: 20180718115545) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -450,6 +450,21 @@ ActiveRecord::Schema.define(version: 20180711224810) do add_index "geozones_polls", ["geozone_id"], name: "index_geozones_polls_on_geozone_id", using: :btree add_index "geozones_polls", ["poll_id"], name: "index_geozones_polls_on_poll_id", using: :btree + create_table "i18n_content_translations", force: :cascade do |t| + t.integer "i18n_content_id", null: false + t.string "locale", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "value" + end + + add_index "i18n_content_translations", ["i18n_content_id"], name: "index_i18n_content_translations_on_i18n_content_id", using: :btree + add_index "i18n_content_translations", ["locale"], name: "index_i18n_content_translations_on_locale", using: :btree + + create_table "i18n_contents", force: :cascade do |t| + t.string "key" + end + create_table "identities", force: :cascade do |t| t.integer "user_id" t.string "provider" From 26965b43ee916cb5ad14e21332ef3926d7fe0cd9 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 20 Jul 2018 15:06:18 -0400 Subject: [PATCH 25/85] Clean I18n codebase --- .../information_texts_controller.rb | 20 ++++++++++++------- app/models/i18n_content.rb | 4 ++-- .../information_texts/_form.html.erb | 2 +- .../information_texts/_form_field.html.erb | 9 +++++---- app/views/welcome/welcome.html.erb | 2 -- config/initializers/i18n_translation.rb | 4 +--- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 6f2e6777d..6a8ecc1f3 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -4,16 +4,21 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz def index existing_keys = {} @tab = params[:tab] || :debates - I18nContent.begins_with_key(@tab).all. - map{|content| existing_keys[content.key] = content } + + I18nContent.begins_with_key(@tab) + .all + .map{ |content| existing_keys[content.key] = content } + @content = {} + I18n.backend.send(:translations)[:en].each do |k,v| - @content[k.to_s] = flat_hash(v).keys.map{|s| existing_keys["#{k.to_s}.#{s}"].nil? ? + @content[k.to_s] = flat_hash(v).keys + .map{ |s| existing_keys["#{k.to_s}.#{s}"].nil? ? I18nContent.new(key: "#{k.to_s}.#{s}") : existing_keys["#{k.to_s}.#{s}"] } end - @content = @content[@tab.to_s] + @content = @content[@tab.to_s] end def update @@ -25,6 +30,7 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz text.save end end + redirect_to admin_site_customization_information_texts_path end @@ -48,16 +54,16 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz end def delete_translations - languages_to_delete = params[:delete_translations].select { |k, v| params[:delete_translations][k] == "1" }.keys + languages_to_delete = params[:delete_translations].select { |k, v| params[:delete_translations][k] == '1' }.keys languages_to_delete.each do |locale| I18nContentTranslation.destroy_all(locale: locale) end end - def flat_hash(h, f=nil, g={}) + def flat_hash(h, f = nil, g = {}) return g.update({ f => h }) unless h.is_a? Hash h.each { |k, r| flat_hash(r, [f,k].compact.join('.'), g) } - g + return g end end diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb index 48192d0ef..d7914c83a 100644 --- a/app/models/i18n_content.rb +++ b/app/models/i18n_content.rb @@ -1,11 +1,11 @@ class I18nContent < ActiveRecord::Base scope :by_key, -> (key){ where(key: key) } - scope :begins_with_key, -> (key){ where("key LIKE ?", "#{key}?%") } + scope :begins_with_key, -> (key){ where("key ILIKE ?", "#{key}?%") } validates :key, uniqueness: true translates :value, touch: true globalize_accessors locales: [:en, :es, :fr, :nl, :val, :pt_br] -end \ No newline at end of file +end diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/views/admin/site_customization/information_texts/_form.html.erb index d3c0489b7..665db0a8c 100644 --- a/app/views/admin/site_customization/information_texts/_form.html.erb +++ b/app/views/admin/site_customization/information_texts/_form.html.erb @@ -8,7 +8,7 @@ <% group.each do |content| %> <%= t(content[:key]) %> <% content.globalize_locales.each do |locale| %> - <%= render 'form_field', content: content, locale: locale %> + <%= render "form_field", content: content, locale: locale %> <% end %> <% end %> <% end %> diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index f247870f4..7ee77299b 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -2,8 +2,9 @@ <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", content.send("value_#{locale}"), - {rows: 5, - class: "js-globalize-attribute", - style: display_translation?(locale), - data: { locale: locale }} %> + { rows: 5, + class: "js-globalize-attribute", + style: display_translation?(locale), + data: { locale: locale } + } %> <% end %> diff --git a/app/views/welcome/welcome.html.erb b/app/views/welcome/welcome.html.erb index abd3c15a0..d647ba8e6 100644 --- a/app/views/welcome/welcome.html.erb +++ b/app/views/welcome/welcome.html.erb @@ -1,9 +1,7 @@

        <%= t("welcome.welcome.title") %>

        -

        <%= t("welcome.welcome.user_permission_info") %>

        -1
        •  <%= t("welcome.welcome.user_permission_debates") %>
        •  <%= t("welcome.welcome.user_permission_proposal") %>
        • diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb index 0ee8606b6..ca1ec8cfd 100644 --- a/config/initializers/i18n_translation.rb +++ b/config/initializers/i18n_translation.rb @@ -1,8 +1,7 @@ -require 'action_view/helpers/tag_helper' require 'i18n/exceptions' +require 'action_view/helpers/tag_helper' module ActionView - # = Action View Translation Helpers module Helpers module TranslationHelper include TagHelper @@ -19,7 +18,6 @@ module ActionView end translate(key, options) end - end end end From f92006b3f30aa14889e0c2ffb93cd29caee444c9 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 20 Jul 2018 15:23:54 -0400 Subject: [PATCH 26/85] Extract complex logic from `InformationTexts#index` into separate private methods --- .../information_texts_controller.rb | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 6a8ecc1f3..31fc5f5a9 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -2,22 +2,8 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz include Translatable def index - existing_keys = {} - @tab = params[:tab] || :debates - - I18nContent.begins_with_key(@tab) - .all - .map{ |content| existing_keys[content.key] = content } - - @content = {} - - I18n.backend.send(:translations)[:en].each do |k,v| - @content[k.to_s] = flat_hash(v).keys - .map{ |s| existing_keys["#{k.to_s}.#{s}"].nil? ? - I18nContent.new(key: "#{k.to_s}.#{s}") : - existing_keys["#{k.to_s}.#{s}"] } - end - + fetch_existing_keys + append_or_create_keys @content = @content[@tab.to_s] end @@ -60,6 +46,26 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz end end + def fetch_existing_keys + existing_keys = {} + @tab = params[:tab] || :debates + + I18nContent.begins_with_key(@tab) + .all + .map{ |content| existing_keys[content.key] = content } + end + + def append_or_create_keys + @content = {} + + I18n.backend.send(:translations)[:en].each do |k, v| + @content[k.to_s] = flat_hash(v).keys + .map{ |s| existing_keys["#{k.to_s}.#{s}"].nil? ? + I18nContent.new(key: "#{k.to_s}.#{s}") : + existing_keys["#{k.to_s}.#{s}"] } + end + end + def flat_hash(h, f = nil, g = {}) return g.update({ f => h }) unless h.is_a? Hash h.each { |k, r| flat_hash(r, [f,k].compact.join('.'), g) } From bc152acaf2704e8e035b2f660d538287365fbca2 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 20 Jul 2018 15:29:34 -0400 Subject: [PATCH 27/85] Don't evaluate a conditional and assign a variable on the same line --- config/initializers/i18n_translation.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb index ca1ec8cfd..cf3703ce2 100644 --- a/config/initializers/i18n_translation.rb +++ b/config/initializers/i18n_translation.rb @@ -7,15 +7,19 @@ module ActionView include TagHelper def t(key, options = {}) - if translation = I18nContent.by_key(key).last + translation = I18nContent.by_key(key).last + + if translation.present? Globalize.with_locale(locale) do string = I18nContent.where(key: key).first.value options.each do |key, value| string.sub! "%{#{key}}", (value || "%{#{key}}") end + return string.html_safe end end + translate(key, options) end end From a190e3e1e0b9f4b04ebe9b475cd1a2adc7820cf5 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 23 Jul 2018 08:06:01 -0400 Subject: [PATCH 28/85] Fix exception for undeclared variable on InformationTexts#index action --- .../site_customization/information_texts_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 31fc5f5a9..8ea90382d 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -47,12 +47,12 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz end def fetch_existing_keys - existing_keys = {} + @existing_keys = {} @tab = params[:tab] || :debates I18nContent.begins_with_key(@tab) .all - .map{ |content| existing_keys[content.key] = content } + .map{ |content| @existing_keys[content.key] = content } end def append_or_create_keys @@ -60,9 +60,9 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz I18n.backend.send(:translations)[:en].each do |k, v| @content[k.to_s] = flat_hash(v).keys - .map{ |s| existing_keys["#{k.to_s}.#{s}"].nil? ? + .map{ |s| @existing_keys["#{k.to_s}.#{s}"].nil? ? I18nContent.new(key: "#{k.to_s}.#{s}") : - existing_keys["#{k.to_s}.#{s}"] } + @existing_keys["#{k.to_s}.#{s}"] } end end From 983dcf02473d40117a05fb415b4f491c8d8349a2 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 23 Jul 2018 08:07:13 -0400 Subject: [PATCH 29/85] Move 'Custom information texts' menu option under 'Site content' --- app/views/admin/_menu.html.erb | 8 ++++---- config/locales/en/admin.yml | 5 +++-- config/locales/es/admin.yml | 1 + 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index d6c31a892..dc08fbc4e 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -121,6 +121,10 @@
        • > <%= link_to t("admin.menu.banner"), admin_banners_path %>
        • + +
        • > + <%= link_to t("admin.menu.site_customization.information_texts"), admin_site_customization_information_texts_path %> +
        @@ -237,10 +241,6 @@
      • > <%= link_to t("admin.menu.site_customization.content_blocks"), admin_site_customization_content_blocks_path%>
      • - -
      • > - <%= link_to t("admin.menu.site_customization.information_texts"), admin_site_customization_information_texts_path%> -
    diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 259ea7c44..399c6b72f 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -538,9 +538,10 @@ en: signature_sheets: Signature Sheets site_customization: homepage: Homepage - pages: Custom Pages - images: Custom Images + pages: Custom pages + images: Custom images content_blocks: Custom content blocks + information_texts: Custom information texts title_moderated_content: Moderated content title_budgets: Budgets title_polls: Polls diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 00cd907a3..6dfddf123 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -542,6 +542,7 @@ es: pages: Personalizar páginas images: Personalizar imágenes content_blocks: Personalizar bloques + information_texts: Personalizar textos title_moderated_content: Contenido moderado title_budgets: Presupuestos title_polls: Votaciones From 5c1e0bd94951fb16de375526ffaf47a6e71f8928 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 23 Jul 2018 10:52:45 -0400 Subject: [PATCH 30/85] Don't use hardcoded locale when appending/creating I18n keys --- .../site_customization/information_texts_controller.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 8ea90382d..278b6a03d 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -57,10 +57,15 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz def append_or_create_keys @content = {} + translations = if params[:locale].present? + I18n.backend.send(:translations)[params[:locale].to_sym] + else + I18n.backend.send(:translations)[I18n.locale.to_sym] + end - I18n.backend.send(:translations)[:en].each do |k, v| + translations.each do |k, v| @content[k.to_s] = flat_hash(v).keys - .map{ |s| @existing_keys["#{k.to_s}.#{s}"].nil? ? + .map { |s| @existing_keys["#{k.to_s}.#{s}"].nil? ? I18nContent.new(key: "#{k.to_s}.#{s}") : @existing_keys["#{k.to_s}.#{s}"] } end From ca57a65aae2e96b84af80ecef0a137e28738270b Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 23 Jul 2018 10:53:50 -0400 Subject: [PATCH 31/85] Add missing I18n keys for InformationTexts#index view --- .../information_texts/_form.html.erb | 2 +- config/locales/en/admin.yml | 12 ++++++++++++ config/locales/es/admin.yml | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/views/admin/site_customization/information_texts/_form.html.erb index 665db0a8c..f43672e5b 100644 --- a/app/views/admin/site_customization/information_texts/_form.html.erb +++ b/app/views/admin/site_customization/information_texts/_form.html.erb @@ -12,5 +12,5 @@ <% end %> <% end %> <% end %> - <%= submit_tag "Save", class: "button" %> + <%= submit_tag t("admin.menu.site_customization.buttons.save"), class: "button" %> <% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 399c6b72f..bdab78e9e 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -542,6 +542,18 @@ en: images: Custom images content_blocks: Custom content blocks information_texts: Custom information texts + information_texts_menu: + debates: "Debates" + community: "Community" + proposals: "Proposals" + polls: "Polls" + layouts: "Layouts" + emails: "Emails" + management: "Management" + guides: "Guides" + welcome: "Welcome" + buttons: + save: "Save" title_moderated_content: Moderated content title_budgets: Budgets title_polls: Polls diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 6dfddf123..9592847ba 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -543,6 +543,18 @@ es: images: Personalizar imágenes content_blocks: Personalizar bloques information_texts: Personalizar textos + information_texts_menu: + debates: "Debates" + community: "Comunidad" + proposals: "Propuestas" + polls: "Votaciones" + layouts: "Plantillas" + emails: "Correos" + management: "Gestión" + guides: "Guías" + welcome: "Bienvenido/a" + buttons: + save: "Guardar cambios" title_moderated_content: Contenido moderado title_budgets: Presupuestos title_polls: Votaciones From b8b0f64e64bea7c6c10029493f5d349a24293fa8 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Mon, 23 Jul 2018 14:25:30 -0400 Subject: [PATCH 32/85] Rename `emails` key with `mailers` key --- .../admin/site_customization/information_texts/_tabs.html.erb | 2 +- config/locales/en/admin.yml | 2 +- config/locales/es/admin.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/admin/site_customization/information_texts/_tabs.html.erb b/app/views/admin/site_customization/information_texts/_tabs.html.erb index e3ba440c9..ef3379f11 100644 --- a/app/views/admin/site_customization/information_texts/_tabs.html.erb +++ b/app/views/admin/site_customization/information_texts/_tabs.html.erb @@ -1,5 +1,5 @@
      - <% [:debates, :community, :proposals, :polls, :layouts, :emails, :management, :guides, :welcome].each do |tab| %> + <% [:debates, :community, :proposals, :polls, :layouts, :mailers, :management, :guides, :welcome].each do |tab| %>
    • "> <%= link_to t("admin.menu.site_customization.information_texts_menu.#{tab}"), admin_site_customization_information_texts_path(tab: tab) %>
    • diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index bdab78e9e..792399416 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -548,7 +548,7 @@ en: proposals: "Proposals" polls: "Polls" layouts: "Layouts" - emails: "Emails" + mailers: "Emails" management: "Management" guides: "Guides" welcome: "Welcome" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 9592847ba..b388fe7d0 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -549,7 +549,7 @@ es: proposals: "Propuestas" polls: "Votaciones" layouts: "Plantillas" - emails: "Correos" + mailers: "Correos" management: "Gestión" guides: "Guías" welcome: "Bienvenido/a" From f521188cd0ad70eaeb16f0a08fe961eaaf33f755 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 24 Jul 2018 15:05:07 +0200 Subject: [PATCH 33/85] Fix specs with recently updated I18n values --- spec/features/admin/site_customization/images_spec.rb | 6 +++--- spec/features/admin/site_customization/pages_spec.rb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/admin/site_customization/images_spec.rb b/spec/features/admin/site_customization/images_spec.rb index cd8c0c065..7e0f24f01 100644 --- a/spec/features/admin/site_customization/images_spec.rb +++ b/spec/features/admin/site_customization/images_spec.rb @@ -11,7 +11,7 @@ feature "Admin custom images" do visit admin_root_path within("#side_menu") do - click_link "Custom Images" + click_link "Custom images" end within("tr.logo_header") do @@ -27,7 +27,7 @@ feature "Admin custom images" do visit admin_root_path within("#side_menu") do - click_link "Custom Images" + click_link "Custom images" end within("tr.icon_home") do @@ -43,7 +43,7 @@ feature "Admin custom images" do visit admin_root_path within("#side_menu") do - click_link "Custom Images" + click_link "Custom images" end within("tr.social_media_icon") do diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb index d4873be9d..7b586c042 100644 --- a/spec/features/admin/site_customization/pages_spec.rb +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -19,7 +19,7 @@ feature "Admin custom pages" do visit admin_root_path within("#side_menu") do - click_link "Custom Pages" + click_link "Custom pages" end expect(page).not_to have_content "An example custom page" @@ -44,7 +44,7 @@ feature "Admin custom pages" do visit admin_root_path within("#side_menu") do - click_link "Custom Pages" + click_link "Custom pages" end click_link "An example custom page" From 7255c6cb9bc19e1b4fddd7f2736bfa61b92d2513 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 24 Jul 2018 14:51:01 -0400 Subject: [PATCH 34/85] Fallback to default I18n value if translation is not available --- config/initializers/i18n_translation.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb index cf3703ce2..293a4729b 100644 --- a/config/initializers/i18n_translation.rb +++ b/config/initializers/i18n_translation.rb @@ -12,11 +12,12 @@ module ActionView if translation.present? Globalize.with_locale(locale) do string = I18nContent.where(key: key).first.value + options.each do |key, value| string.sub! "%{#{key}}", (value || "%{#{key}}") end - return string.html_safe + return string.html_safe unless string.nil? end end From 277fb95f1c3af69f2f5cae06492526c482d8f5f2 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 24 Jul 2018 15:18:31 -0400 Subject: [PATCH 35/85] Remove unnecessary I18n YAML files --- config/locales/en/i18n_contents.yml | 180 ---------------------------- config/locales/es/i18n_contents.yml | 180 ---------------------------- 2 files changed, 360 deletions(-) delete mode 100644 config/locales/en/i18n_contents.yml delete mode 100644 config/locales/es/i18n_contents.yml diff --git a/config/locales/en/i18n_contents.yml b/config/locales/en/i18n_contents.yml deleted file mode 100644 index 9c7409749..000000000 --- a/config/locales/en/i18n_contents.yml +++ /dev/null @@ -1,180 +0,0 @@ -en: - budgets: - index: - section_footer: - description: 'Debates section description' - help_text_1: 'Help text 1 for debates section' - help_text_2: 'Help text 2 for debates section' - help_text_3: 'Help text 3 for debates section' - help_text_4: 'Help text 4 for debates section' - community: - topic: - sidebar: - recommendation_one: 'Recommendation 1 when create a topic on a proposal community' - recommendation_two: 'Recommendation 2 when create a topic on a proposal community' - recommendation_three: 'Recommendation 3 when create a topic on a proposal community' - devise: - registrations: - destroyed: 'Message when deleting an account' - devise_views: - mailer: - confirmation_instructions: - title: 'Confirmation email title' - debates: - index: - section_footer: - description: 'Debates section description' - help_text_1: 'Help text 1 for debates section' - help_text_2: 'Help text 2 for debates section' - help_text_3: 'Help text 3 for debates section' - new: - recommendation_one: 'Recommendation 1 when creating debates' - recommendation_two: 'Recommendation 2 when creating debates' - recommendation_three: 'Recommendation 3 when creating debates' - recommendation_four: 'Recommendation 4 when creating debates' - layouts: - footer: - accessibility: 'Accessibility link name' - conditions: 'Conditions link name' - privacy: 'Privary policy link name' - proposals: - index: - section_footer: - description: 'Proposal page description' - help_text_1: 'Help text 1 of proposal page' - help_text_2: 'Help text 2 of proposal page' - help_text_3: 'Help text 3 of proposal page' - new: - form: - submit_button: '"Create proposal" button text' - more_info: '"More information" text in new proposal' - recommendation_one: 'Recommendation 1 in new proposal' - recommendation_two: 'Recommendation 2 in new proposal' - recommendation_three: 'Recommendation 3 in new proposal' - proposal: - reason_for_supports_necessary: 'Supports needed for proposal' - polls: - index: - section_footer: - description: 'Polls description' - help_text_1: 'Help text 1 of polls' - help_text_2: 'Help text 2 of polls' - legislation: - processes: - index: - section_footer: - description: 'Legislation processes description' - help_text_1: 'Help text 1 of legislation processes' - help_text_2: 'Help text 2 of legislation processes' - help_text_3: 'Help text 3 of legislation processes' - management: - print: - proposals_info: 'Printed proposal information' - proposals_note: 'Printed proposal note' - proposals_title: 'Printed proposal title' - budget_investments_info: 'Printed budget investments information' - budgets_investments_note: 'Printed budget investments note' - guides: - title: 'Guides titles' - subtitle: 'Guides subtitle' - budget_investment: - title: 'Budget investments guides title' - feature_1_html: 'Budget investments guides feature 1' - feature_2_html: 'Budget investments guides feature 2' - feature_3_html: 'Budget investments guides feature 3' - feature_4_html: 'Budget investments guides feature 4' - new_button: 'New investment button' - proposal: - title: 'Proposal guides title' - feature_1_html: 'Proposal guides feature 1' - feature_2_html: 'Proposal guides feature 2' - feature_3_html: 'Proposal guides feature 3' - feature_4_html: 'Proposal guides feature 4' - new_button: 'New proposal button' - mailers: - no_reply: 'No reply message' - comment: - hi: 'New comment email greetings' - new_comment_by_html: 'New comment text' - subject: 'New comment subject' - title: 'New comment title' - config: - manage_email_subscriptions: 'Manage email subscriptions' - email_verification: - click_here_to_verify: 'Link name to verify account' - instructions_2_html: 'Instructions to verify account 2' - instructions_html: 'Instructions to verify account' - subject: 'verify account subject' - thanks: 'Thanks' - title: 'Verify account title' - reply: - hi: 'New answer greetings' - new_reply_by_html: 'New answer text' - subject: 'New answer subject' - title: 'New answer title' - unfeasible_spending_proposal: - hi: 'Unfeasible spending proposal greetings' - reconsider_html: 'Unfeasible spending proposal reconsider text' - sincerely: 'Unfeasible spending proposal sincerely' - signatory: 'Unfeasible spending proposal signatory' - sorry: 'Unfeasible spending proposal sorry' - subject: 'Unfeasible spending proposal subject' - unfeasible_html: 'Unfeasible spending proposal text' - budget_investment_unfeasible: - hi: 'Budget investment unfeasible greetings' - reconsider_html: 'Budget investment unfeasible reconsider text' - sincerely: 'Budget investment unfeasible sincerely' - signatory: 'Budget investment unfeasible signatory' - sorry: 'Budget investment unfeasible sorry' - subject: 'Budget investment unfeasible subject' - unfeasible_html: 'Budget investment unfeasible text' - proposal_notification_digest: - info: 'Proposal notification digest information' - title: 'Proposal notification digest title' - share: 'Proposal notification digest share' - comment: 'Proposal notification digest share button' - unsubscribe: 'Proposal notification digest unsubscribe' - unsubscribe_account: 'Proposal notification digest unsubscribe link text' - direct_message_for_receiver: - subject: 'New direct message subject' - reply: 'Reply message subject button text' - unsubscribe: 'Unsubscribe direct messages emails' - unsubscribe_account: 'Unsubscribe direct message emails link text' - direct_message_for_sender: - subject: 'Direct message sender subject' - title_html: 'Direct message sender title' - user_invite: - ignore: 'User invitation ignore' - text: 'User invitation text' - thanks: 'User invitation thanks' - title: 'User invitation title' - button: 'User invitation button' - subject: 'User invitation subject' - budget_investment_created: - subject: 'Budget investment created subject' - title: 'Budget investment created title' - intro_html: 'Budget investment created intro' - text_html: 'Budget investment created text' - follow_html: 'Budget investment created follow' - follow_link: 'Budget investment created follow link' - sincerely: 'Budget investment created sincerely' - signatory: 'Budget investment created signatory' - share: 'Budget investment created share' - budget_investment_selected: - subject: 'Budget investment selected subject' - hi: 'Budget investment selected greetings' - selected_html: 'Budget investment selected text' - share: 'Budget investment selected share' - share_button: 'Budget investment selected share button' - thanks: 'Budget investment selected thanks' - sincerely: 'Budget investment selected sincerely' - signatory: 'Budget investment selected signatory' - budget_investment_unselected: - subject: 'Budget investment unselected subject' - hi: 'Budget investment unselected greetings' - unselected_html: 'Budget investment unselected text' - participate_html: 'Budget investment unselected participate' - participate_url: 'Budget investment unselected participate URL' - thanks: 'Budget investment unselected thanks' - sincerely: 'Budget investment unselected sincerely' - signatory: 'Budget investment unselected signatory' \ No newline at end of file diff --git a/config/locales/es/i18n_contents.yml b/config/locales/es/i18n_contents.yml deleted file mode 100644 index 0e1ec82cb..000000000 --- a/config/locales/es/i18n_contents.yml +++ /dev/null @@ -1,180 +0,0 @@ -es: - budgets: - index: - section_footer: - description: 'Descripción de la sección de debates' - help_text_1: 'Texto de ayuda 1 para la sección de debates' - help_text_2: 'Texto de ayuda 2 para la sección de debates' - help_text_3: 'Texto de ayuda 3 para la sección de debates' - help_text_4: 'Texto de ayuda 4 para la sección de debates' - community: - topic: - sidebar: - recommendation_one: 'Recomendación 1 en la creación de un tema en la comunidad de propuestas' - recommendation_two: 'Recomendación 2 en la creación de un tema en la comunidad de propuestas' - recommendation_three: 'Recomendación 3 en la creación de un tema en la comunidad de propuestas' - devise: - registrations: - destroyed: 'Mensaje al eliminar una cuenta' - devise_views: - mailer: - confirmation_instructions: - title: 'Título del email de confimación' - debates: - index: - section_footer: - description: 'Descripción de la ayuda del índice de debates' - help_text_1: 'Texto de ayuda 1 del índice de debates' - help_text_2: 'Texto de ayuda 2 del índice de debates' - help_text_3: 'Texto de ayuda 3 del índice de debates' - new: - recommendation_one: 'Recomendación 1 en la creación de debates' - recommendation_two: 'Recomendación 2 en la creación de debates' - recommendation_three: 'Recomendación 3 en la creación de debates' - recommendation_four: 'Recomendación 4 en la creación de debates' - layouts: - footer: - accessibility: 'Nombre enlace accesibilidad' - conditions: 'Nombre enlace condiciones de uso' - privacy: 'Nombre enlace política de privacidad' - proposals: - index: - section_footer: - description: 'Descripción de la página de propuestas' - help_text_1: 'Texto de ayuda 1 en la página de propuestas' - help_text_2: 'Texto de ayuda 2 en la página de propuestas' - help_text_3: 'Texto de ayuda 3 en la página de propuestas' - new: - form: - submit_button: 'Texto del botón "Crear propuesta"' - more_info: 'Texto "Más información" de la página de nueva propuesta' - recommendation_one: 'Recomendación 1 de la página de nueva propuesta' - recommendation_two: 'Recomendación 2 de la página de nueva propuesta' - recommendation_three: 'Recomendación 3 de la página de nueva propuesta' - proposal: - reason_for_supports_necessary: 'Número de apoyos necesarios para las propuestas' - polls: - index: - section_footer: - description: 'Descripción de la página de votaciones' - help_text_1: 'Texto de ayuda 1 en la página de votaciones' - help_text_2: 'Texto de ayuda 2 en la página de votaciones' - legislation: - processes: - index: - section_footer: - description: 'Descripción procesos legislativos' - help_text_1: 'Texto ayuda 1 procesos legislativos' - help_text_2: 'Texto ayuda 2 procesos legislativos' - help_text_3: 'Texto ayuda 3 procesos legislativos' - management: - print: - proposals_info: 'Información de propuestas (impresas)' - proposals_note: 'Nota de propuetas (impresas)' - proposals_title: 'Título de propuestas (impresas)' - budget_investments_info: 'Información de proyectos (impresos)' - budgets_investments_note: 'Notas de proyectos (impresos)' - guides: - title: 'Título de las guías' - subtitle: 'Subtítulo de las guías' - budget_investment: - title: 'Título de guías de presupuestos' - feature_1_html: 'Característica 1 de presupuestos' - feature_2_html: 'Característica 2 de presupuestos' - feature_3_html: 'Característica 3 de presupuestos' - feature_4_html: 'Característica 4 de presupuestos' - new_button: 'Botón de nuevo presupuesto' - proposal: - title: 'Título de guías de propuestas' - feature_1_html: 'Característica 1 de propuestas' - feature_2_html: 'Característica 2 de propuestas' - feature_3_html: 'Característica 3 de propuestas' - feature_4_html: 'Característica 4 de propuestas' - new_button: 'Botón de nueva propuesta' - mailers: - no_reply: 'Mensaje de no contestar' - comment: - hi: 'Saludo email nuevo comentario' - new_comment_by_html: 'Texto nuevo comentario' - subject: 'Asunto nuevo comentario' - title: 'Título nuevo comentario' - config: - manage_email_subscriptions: 'Gestionar subscripciones de emails' - email_verification: - click_here_to_verify: 'Nombre enlace para verificar la cuenta' - instructions_2_html: 'Instrucciones para verificar la cuenta 2' - instructions_html: 'Instrucciones para verificar la cuenta' - subject: 'Asunto verificar la cuenta' - thanks: 'Agradecimientos' - title: 'Título email verificación' - reply: - hi: 'Saludo email nueva respuesta' - new_reply_by_html: 'Texto email nueva respuesta' - subject: 'Asunto email nueva respuesta' - title: 'Título email nueva respuesta' - unfeasible_spending_proposal: - hi: 'Saludo email proyecto inviable' - reconsider_html: 'Texto para reconsiderar el proyecto' - sincerely: 'Saludo final' - signatory: 'Firma' - sorry: 'Disculpas' - subject: 'Asunto' - unfeasible_html: 'Texto email inviable' - budget_investment_unfeasible: - hi: 'Saludo email proyecto inviable' - reconsider_html: 'Texto para reconsiderar la proyecto' - sincerely: 'Saludo final' - signatory: 'Firma' - sorry: 'Disculpas' - subject: 'Asunto' - unfeasible_html: 'Texto email inviable' - proposal_notification_digest: - info: 'Información resumen propuestas' - title: 'Título resumen propuestas' - share: 'Texto compartir propuesta' - comment: 'Texto comentar propuesta' - unsubscribe: 'Cancelar subscripción' - unsubscribe_account: 'Texto enlace cancelar subscripción' - direct_message_for_receiver: - subject: 'Asunto nuevo mensaje privado' - reply: 'Texto enlace responder mensaje privado' - unsubscribe: 'Cancelar avisos de mensajes privados' - unsubscribe_account: 'Texto enlace cancelar subscripción' - direct_message_for_sender: - subject: 'Asunto email envío mensaje privado' - title_html: 'Título email envío mensaje privado' - user_invite: - ignore: 'Ignorar correo de invitación' - text: 'Texto email invitación' - thanks: 'Agradecimiento email invitación' - title: 'Título email invitación' - button: 'Botón email invitación' - subject: 'Asunto email invitación' - budget_investment_created: - subject: 'Asunto email proyecto de inversión' - title: 'Título email proyecto de inversión' - intro_html: 'Saludo' - text_html: 'Texto' - follow_html: 'Texto seguir proceso' - follow_link: 'Texto link seguir proceso' - sincerely: 'Saludo final' - signatory: 'Firma' - share: 'Texto compartir' - budget_investment_selected: - subject: 'Asunto' - hi: 'Saludo' - selected_html: 'Texto seleccionado' - share: 'Compartir' - share_button: 'Botón compartir' - thanks: 'Agradecimientos' - sincerely: 'Saludo final' - signatory: 'Firma' - budget_investment_unselected: - subject: 'Asunto' - hi: 'Saludo' - unselected_html: 'Texto no seleccionado' - participate_html: 'Texto seguir participando' - participate_url: 'URL seguir participando' - thanks: 'Agradecimientos' - sincerely: 'Saludo final' - signatory: 'Firma' \ No newline at end of file From dd42b7ffbd0abf549d2768ad652fe92312b2dd81 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 24 Jul 2018 15:58:10 -0400 Subject: [PATCH 36/85] Correctly highlight 'Custom information texts' option on menu if active --- app/helpers/admin_helper.rb | 2 +- app/views/admin/_menu.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 988d03a00..91565fb73 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -37,7 +37,7 @@ module AdminHelper end def menu_customization? - ["pages", "banners"].include?(controller_name) || menu_homepage? + ["pages", "banners", "information_texts"].include?(controller_name) || menu_homepage? end def menu_homepage? diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index dc08fbc4e..df355b3af 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -110,7 +110,7 @@
        > -
      • > +
      • > <%= link_to t("admin.menu.site_customization.homepage"), admin_homepage_path %>
      • From 4c2eedf8bda5351aa1d9cab92250e29ba85c3629 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 24 Jul 2018 20:04:07 -0400 Subject: [PATCH 37/85] Add French I18n keys for InformationTexts#index view --- config/locales/fr/admin.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/locales/fr/admin.yml b/config/locales/fr/admin.yml index 7c2d63e03..0b1f7acc3 100644 --- a/config/locales/fr/admin.yml +++ b/config/locales/fr/admin.yml @@ -225,6 +225,19 @@ fr: pages: Pages personnalisées images: Images personnalisées content_blocks: Blocs de contenu personnalisés + information_texts: "Textes d'information personnalisés" + information_texts_menu: + debates: "Débats" + community: "Communauté" + proposals: "Propositions" + polls: "Votes" + layouts: "Dessins" + mailers: "Courriels" + management: "Gestion" + guides: "Guides" + welcome: "Bienvenue" + buttons: + save: "Enregistrer" title_categories: Catégories title_moderated_content: Contenu modéré title_budgets: Budgets From 42eb784922cec3ebddc449b98dac54bf6cb0ce16 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 24 Jul 2018 20:16:53 -0400 Subject: [PATCH 38/85] Add specs for basic Admin Globalize feature --- .../information_texts/_tabs.html.erb | 2 +- spec/factories.rb | 6 + .../information_texts_spec.rb | 115 ++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 spec/features/admin/site_customization/information_texts_spec.rb diff --git a/app/views/admin/site_customization/information_texts/_tabs.html.erb b/app/views/admin/site_customization/information_texts/_tabs.html.erb index ef3379f11..ca5061bc3 100644 --- a/app/views/admin/site_customization/information_texts/_tabs.html.erb +++ b/app/views/admin/site_customization/information_texts/_tabs.html.erb @@ -1,4 +1,4 @@ -
          +
            <% [:debates, :community, :proposals, :polls, :layouts, :mailers, :management, :guides, :welcome].each do |tab| %>
          • "> <%= link_to t("admin.menu.site_customization.information_texts_menu.#{tab}"), admin_site_customization_information_texts_path(tab: tab) %> diff --git a/spec/factories.rb b/spec/factories.rb index beb64aa2d..4eb46eee8 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1038,4 +1038,10 @@ LOREM_IPSUM factory :widget_feed, class: 'Widget::Feed' do end + factory :i18n_content, class: 'I18nContent' do + key 'debates.index.section_footer.description' + value_es 'Texto en español' + value_en 'Text in english' + end + end diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb new file mode 100644 index 000000000..affd32082 --- /dev/null +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -0,0 +1,115 @@ +require 'rails_helper' + +feature "Admin custom information texts" do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'page is correctly loaded' do + visit admin_site_customization_information_texts_path + + click_link 'Debates' + expect(page).to have_content 'Help about citizen debates' + + click_link 'Community' + expect(page).to have_content 'Access the community' + + click_link 'Proposals' + expect(page).to have_content 'Proposal type' + + within "#information-texts-tabs" do + click_link "Polls" + end + + expect(page).to have_content 'Results' + + click_link 'Layouts' + expect(page).to have_content 'Accessibility' + + click_link 'Emails' + expect(page).to have_content 'Confirm your email' + + within "#information-texts-tabs" do + click_link "Management" + end + + expect(page).to have_content 'This user account is already verified.' + + click_link 'Guides' + expect(page).to have_content 'Choose what you want to create' + + click_link 'Welcome' + expect(page).to have_content 'See all recommended debates' + end + + scenario 'can be changed and they are correctly shown' do + content = create(:i18n_content) + old_text = content.value_en + + visit admin_site_customization_information_texts_path + + select 'English', from: 'translation_locale' + fill_in "contents_content_#{content.key}values_value_en", with: 'Custom debates text' + click_button "Save" + + visit debates_path + + expect(page).to have_content 'Custom debates text' + expect(page).not_to have_content old_text + end + + scenario 'change according to current locale', :js do + content = create(:i18n_content) + + visit debates_path + + expect(page).to have_content content.value_en + expect(page).not_to have_content content.value_es + + select('Español', from: 'locale-switcher') + + expect(page).to have_content content.value_es + expect(page).not_to have_content content.value_en + end + + scenario 'languages can be added', :js do + content = create(:i18n_content, key: 'debates.form.debate_text') + + visit admin_site_customization_information_texts_path(locale: :fr) + + select 'Français', from: 'translation_locale' + + click_link 'Français' + expect(page).to have_css('a.is-active', text: 'Français') + + fill_in "contents_content_#{content.key}values_value_fr", with: 'Nouvelle titre en français' + click_button 'Enregistrer' + + content.reload + + expect(page).to have_content 'Nouvelle titre en français' + expect(content.value_fr).to eq 'Nouvelle titre en français' + end + + scenario 'languages can be removed', :js do + content = create(:i18n_content) + + visit admin_site_customization_information_texts_path + + click_link 'Español' + expect(page).to have_css('a.is-active', text: 'Español') + + click_link 'Remove language' + expect(page).not_to have_link('Español') + + click_button 'Save' + + content.reload + + expect(content.value_es).to be nil + expect(page).not_to have_content 'Texto en español' + end + +end From 079124e3ddf243f9df454cb2a558cd84c9c33eae Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 25 Jul 2018 08:37:42 -0400 Subject: [PATCH 39/85] Show current translation or I18n value for locale on textarea --- .../site_customization/information_texts/_form_field.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index 7ee77299b..899d43e2e 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -1,7 +1,7 @@ <% globalize(locale) do %> <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", - content.send("value_#{locale}"), + content.value || t(content.key), { rows: 5, class: "js-globalize-attribute", style: display_translation?(locale), From 0e82fa72a26451899201d086cc57904d6a7ab5d3 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 25 Jul 2018 11:41:58 -0400 Subject: [PATCH 40/85] Do not translate original I18n value on label --- .../admin/site_customization/information_texts/_form.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/views/admin/site_customization/information_texts/_form.html.erb index f43672e5b..cc58da15d 100644 --- a/app/views/admin/site_customization/information_texts/_form.html.erb +++ b/app/views/admin/site_customization/information_texts/_form.html.erb @@ -6,7 +6,7 @@ <% end %> <% contents.each do |group| %> <% group.each do |content| %> - <%= t(content[:key]) %> + <%= I18n.translate(content.key) %> <% content.globalize_locales.each do |locale| %> <%= render "form_field", content: content, locale: locale %> <% end %> From 113981c5732ba5cb2afa111944f8e4f1036ea7c8 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 09:38:31 -0400 Subject: [PATCH 41/85] Avoid unnecessary DB call on I18nTranslation initializer --- config/initializers/i18n_translation.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb index 293a4729b..9c7ad66da 100644 --- a/config/initializers/i18n_translation.rb +++ b/config/initializers/i18n_translation.rb @@ -7,11 +7,11 @@ module ActionView include TagHelper def t(key, options = {}) - translation = I18nContent.by_key(key).last + translation = I18nContent.by_key(key) if translation.present? Globalize.with_locale(locale) do - string = I18nContent.where(key: key).first.value + string = translation.first.value options.each do |key, value| string.sub! "%{#{key}}", (value || "%{#{key}}") From 82f496ccfa5a76c85c6bca8832b28c2356f8cefa Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 26 Jul 2018 22:56:36 +0200 Subject: [PATCH 42/85] Fix globalization for information texts Refactoring and making similar specs to the milestones globalization specs --- .../information_texts_controller.rb | 22 +++- .../information_texts/_form_field.html.erb | 4 +- .../information_texts_spec.rb | 103 +++++++++++++++++- 3 files changed, 121 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 278b6a03d..6aa48cc1a 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -9,15 +9,25 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz def update content_params.each do |content| - value = content[:values].slice(*translation_params(content[:values])) - unless value.empty? - text = I18nContent.by_key(content[:id]).last || I18nContent.create(key: content[:id]) - text.update(value) - text.save + values = content[:values].slice(*translation_params(content[:values])) + + unless values.empty? + values.each do |key, value| + locale = key.split("_").last + + if value == I18n.backend.translate(locale, content[:id]) + next + else + text = I18nContent.find_or_create_by(key: content[:id]) + Globalize.locale = locale + text.update(value: value) + end + end end + end - redirect_to admin_site_customization_information_texts_path + redirect_to admin_site_customization_information_texts_path, notice: "Translation updated successfully" end private diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index 899d43e2e..f8c811814 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -1,7 +1,9 @@ <% globalize(locale) do %> +

            <%= I18nContent.where(key: content.key).first.try(:value) %>

            <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", - content.value || t(content.key), + I18nContent.where(key: content.key).first.try(:value) || + I18n.backend.translate(locale, content.key), { rows: 5, class: "js-globalize-attribute", style: display_translation?(locale), diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index affd32082..424ee59e9 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -17,7 +17,7 @@ feature "Admin custom information texts" do expect(page).to have_content 'Access the community' click_link 'Proposals' - expect(page).to have_content 'Proposal type' + expect(page).to have_content 'Create proposal' within "#information-texts-tabs" do click_link "Polls" @@ -112,4 +112,105 @@ feature "Admin custom information texts" do expect(page).not_to have_content 'Texto en español' end + + context "Globalization" do + + scenario "Add a translation", :js, :focus do + key = "debates.form.debate_title" + + visit admin_site_customization_information_texts_path + + select "Français", from: "translation_locale" + fill_in "contents_content_#{key}values_value_fr", with: 'Titre personalise du débat' + + click_button "Save" + + expect(page).to have_content 'Translation updated successfully' + + select "Français", from: "translation_locale" + + expect(page).to have_content 'Titre personalise du débat' + expect(page).not_to have_content 'Titre du débat' + end + + scenario "Update a translation", :js do + visit @edit_milestone_url + + click_link "Español" + fill_in 'budget_investment_milestone_description_es', with: 'Descripción correcta en Español' + + click_button 'Update milestone' + expect(page).to have_content "Milestone updated successfully" + + visit budget_investment_path(investment.budget, investment) + + click_link("Milestones (1)") + expect(page).to have_content("Description in English") + + select('Español', from: 'locale-switcher') + click_link("Seguimiento (1)") + + expect(page).to have_content("Descripción correcta en Español") + end + + scenario "Remove a translation", :js do + visit @edit_milestone_url + + click_link "Español" + click_link "Remove language" + + expect(page).not_to have_link "Español" + + click_button "Update milestone" + visit @edit_milestone_url + expect(page).not_to have_link "Español" + end + + context "Globalize javascript interface" do + + scenario "Highlight current locale", :js do + visit @edit_milestone_url + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "English" + + select('Español', from: 'locale-switcher') + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español" + end + + scenario "Highlight selected locale", :js do + visit @edit_milestone_url + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "English" + + click_link "Español" + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español" + end + + scenario "Show selected locale form", :js do + visit @edit_milestone_url + + expect(page).to have_field('budget_investment_milestone_description_en', with: 'Description in English') + + click_link "Español" + + expect(page).to have_field('budget_investment_milestone_description_es', with: 'Descripción en Español') + end + + scenario "Select a locale and add it to the milestone form", :js do + visit @edit_milestone_url + + select "Français", from: "translation_locale" + + expect(page).to have_link "Français" + + click_link "Français" + + expect(page).to have_field('budget_investment_milestone_description_fr') + end + end + + end + end From ad252ca835c9442569a0ac4f60bee2edc6d31c22 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 17:35:47 -0400 Subject: [PATCH 43/85] Translations can be updated correctly --- .../information_texts/_form_field.html.erb | 3 +-- .../information_texts_spec.rb | 24 +++++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index f8c811814..4ae31adec 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -1,8 +1,7 @@ <% globalize(locale) do %> -

            <%= I18nContent.where(key: content.key).first.try(:value) %>

            <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", - I18nContent.where(key: content.key).first.try(:value) || + I18nContent.where(key: content.key).first.try(:value) || I18n.backend.translate(locale, content.key), { rows: 5, class: "js-globalize-attribute", diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index 424ee59e9..1e453fe00 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -115,7 +115,7 @@ feature "Admin custom information texts" do context "Globalization" do - scenario "Add a translation", :js, :focus do + scenario "Add a translation", :js do key = "debates.form.debate_title" visit admin_site_customization_information_texts_path @@ -134,23 +134,21 @@ feature "Admin custom information texts" do end scenario "Update a translation", :js do - visit @edit_milestone_url + key = "debates.form.debate_title" + content = create(:i18n_content, key: key, value_fr: 'Titre personalise du débat') - click_link "Español" - fill_in 'budget_investment_milestone_description_es', with: 'Descripción correcta en Español' + visit admin_site_customization_information_texts_path - click_button 'Update milestone' - expect(page).to have_content "Milestone updated successfully" + select "Français", from: "translation_locale" + fill_in "contents_content_#{key}values_value_fr", with: 'Titre personalise again du débat' - visit budget_investment_path(investment.budget, investment) + click_button 'Save' + expect(page).to have_content 'Translation updated successfully' - click_link("Milestones (1)") - expect(page).to have_content("Description in English") + click_link 'Français' - select('Español', from: 'locale-switcher') - click_link("Seguimiento (1)") - - expect(page).to have_content("Descripción correcta en Español") + expect(page).to have_content 'Titre personalise again du débat' + expect(page).not_to have_content 'Titre personalise du débat' end scenario "Remove a translation", :js do From 9c74fa393d414792d3f8e700603ab3dfb16d5ee3 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 17:48:23 -0400 Subject: [PATCH 44/85] Translations can be removed --- .../information_texts_spec.rb | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index 1e453fe00..ba0a3f9cc 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -152,16 +152,35 @@ feature "Admin custom information texts" do end scenario "Remove a translation", :js do - visit @edit_milestone_url + first_key = "debates.form.debate_title" + debate_title = create(:i18n_content, key: first_key, + value_en: 'Custom debate title', + value_es: 'Título personalizado de debate') + + second_key = "debates.form.debate_text" + debate_text = create(:i18n_content, key: second_key, + value_en: 'Custom debate text', + value_es: 'Texto personalizado de debate') + + visit admin_site_customization_information_texts_path click_link "Español" click_link "Remove language" + click_button "Save" expect(page).not_to have_link "Español" - click_button "Update milestone" - visit @edit_milestone_url - expect(page).not_to have_link "Español" + click_link 'English' + expect(page).to have_content 'Custom debate text' + expect(page).to have_content 'Custom debate title' + + debate_title.reload + debate_text.reload + + expect(debate_text.value_es).to be(nil) + expect(debate_title.value_es).to be(nil) + expect(debate_text.value_en).to eq('Custom debate text') + expect(debate_title.value_en).to eq('Custom debate title') end context "Globalize javascript interface" do From 78a5c0356ebcf1168ab0b7cbdf03605c77944f02 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 27 Jul 2018 00:13:29 +0200 Subject: [PATCH 45/85] Add globalization javascript interface specs --- app/helpers/site_customization_helper.rb | 2 +- .../information_texts_spec.rb | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/helpers/site_customization_helper.rb b/app/helpers/site_customization_helper.rb index 52fb3a940..d9318fd9b 100644 --- a/app/helpers/site_customization_helper.rb +++ b/app/helpers/site_customization_helper.rb @@ -1,5 +1,5 @@ module SiteCustomizationHelper def site_customization_display_translation?(locale) - I18nContentTranslation.existing_languages.include?(neutral_locale(locale)) ? "" : "display: none" + I18nContentTranslation.existing_languages.include?(neutral_locale(locale)) || locale == I18n.locale ? "" : "display: none" end end diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index ba0a3f9cc..b3300eaf6 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -183,10 +183,10 @@ feature "Admin custom information texts" do expect(debate_title.value_en).to eq('Custom debate title') end - context "Globalize javascript interface" do + context "Javascript interface" do scenario "Highlight current locale", :js do - visit @edit_milestone_url + visit admin_site_customization_information_texts_path expect(find("a.js-globalize-locale-link.is-active")).to have_content "English" @@ -196,7 +196,10 @@ feature "Admin custom information texts" do end scenario "Highlight selected locale", :js do - visit @edit_milestone_url + key = "debates.form.debate_title" + content = create(:i18n_content, key: key, value_es: 'Título') + + visit admin_site_customization_information_texts_path expect(find("a.js-globalize-locale-link.is-active")).to have_content "English" @@ -206,25 +209,30 @@ feature "Admin custom information texts" do end scenario "Show selected locale form", :js do - visit @edit_milestone_url + key = "debates.form.debate_title" + content = create(:i18n_content, key: key, + value_en: 'Title', + value_es: 'Título') - expect(page).to have_field('budget_investment_milestone_description_en', with: 'Description in English') + visit admin_site_customization_information_texts_path + + expect(page).to have_field("contents_content_#{key}values_value_en", with: 'Title') click_link "Español" - expect(page).to have_field('budget_investment_milestone_description_es', with: 'Descripción en Español') + expect(page).to have_field("contents_content_#{key}values_value_es", with: 'Título') end scenario "Select a locale and add it to the milestone form", :js do - visit @edit_milestone_url + key = "debates.form.debate_title" + visit admin_site_customization_information_texts_path select "Français", from: "translation_locale" expect(page).to have_link "Français" click_link "Français" - - expect(page).to have_field('budget_investment_milestone_description_fr') + expect(page).to have_field("contents_content_#{key}values_value_fr") end end From feb3df1f935521be9c9c234220b8abe9187f2b60 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 27 Jul 2018 00:23:14 +0200 Subject: [PATCH 46/85] Initialize I18n.backend translations We were getting a 500 error because the translations had not been initialized https://stackoverflow.com/a/4054527 --- .../admin/site_customization/information_texts_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 6aa48cc1a..aba211d54 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -67,6 +67,7 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz def append_or_create_keys @content = {} + I18n.backend.send(:init_translations) unless I18n.backend.initialized? translations = if params[:locale].present? I18n.backend.send(:translations)[params[:locale].to_sym] else From 461a172bd28d712d7c9257a8d2918239423b6616 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 27 Jul 2018 00:26:09 +0200 Subject: [PATCH 47/85] Refactor translations loading for current locale --- .../site_customization/information_texts_controller.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index aba211d54..8a523f989 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -68,11 +68,9 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz def append_or_create_keys @content = {} I18n.backend.send(:init_translations) unless I18n.backend.initialized? - translations = if params[:locale].present? - I18n.backend.send(:translations)[params[:locale].to_sym] - else - I18n.backend.send(:translations)[I18n.locale.to_sym] - end + + locale = params[:locale] || I18n.locale + translations = I18n.backend.send(:translations)[locale.to_sym] translations.each do |k, v| @content[k.to_s] = flat_hash(v).keys From 26deb029374a2b75e000d3ebd73db05fcdec893e Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 18:33:29 -0400 Subject: [PATCH 48/85] Show I18n key on label instead of translation --- .../admin/site_customization/information_texts/_form.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/views/admin/site_customization/information_texts/_form.html.erb index cc58da15d..861315691 100644 --- a/app/views/admin/site_customization/information_texts/_form.html.erb +++ b/app/views/admin/site_customization/information_texts/_form.html.erb @@ -6,7 +6,7 @@ <% end %> <% contents.each do |group| %> <% group.each do |content| %> - <%= I18n.translate(content.key) %> + <%= content.key %> <% content.globalize_locales.each do |locale| %> <%= render "form_field", content: content, locale: locale %> <% end %> From 1255389ef77e54869674fa7b238d6e9ef91c7944 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 18:41:13 -0400 Subject: [PATCH 49/85] Remove redundant translation specs --- .../information_texts_spec.rb | 71 +------------------ 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index b3300eaf6..ddfb11021 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -44,75 +44,6 @@ feature "Admin custom information texts" do expect(page).to have_content 'See all recommended debates' end - scenario 'can be changed and they are correctly shown' do - content = create(:i18n_content) - old_text = content.value_en - - visit admin_site_customization_information_texts_path - - select 'English', from: 'translation_locale' - fill_in "contents_content_#{content.key}values_value_en", with: 'Custom debates text' - click_button "Save" - - visit debates_path - - expect(page).to have_content 'Custom debates text' - expect(page).not_to have_content old_text - end - - scenario 'change according to current locale', :js do - content = create(:i18n_content) - - visit debates_path - - expect(page).to have_content content.value_en - expect(page).not_to have_content content.value_es - - select('Español', from: 'locale-switcher') - - expect(page).to have_content content.value_es - expect(page).not_to have_content content.value_en - end - - scenario 'languages can be added', :js do - content = create(:i18n_content, key: 'debates.form.debate_text') - - visit admin_site_customization_information_texts_path(locale: :fr) - - select 'Français', from: 'translation_locale' - - click_link 'Français' - expect(page).to have_css('a.is-active', text: 'Français') - - fill_in "contents_content_#{content.key}values_value_fr", with: 'Nouvelle titre en français' - click_button 'Enregistrer' - - content.reload - - expect(page).to have_content 'Nouvelle titre en français' - expect(content.value_fr).to eq 'Nouvelle titre en français' - end - - scenario 'languages can be removed', :js do - content = create(:i18n_content) - - visit admin_site_customization_information_texts_path - - click_link 'Español' - expect(page).to have_css('a.is-active', text: 'Español') - - click_link 'Remove language' - expect(page).not_to have_link('Español') - - click_button 'Save' - - content.reload - - expect(content.value_es).to be nil - expect(page).not_to have_content 'Texto en español' - end - - context "Globalization" do scenario "Add a translation", :js do @@ -223,7 +154,7 @@ feature "Admin custom information texts" do expect(page).to have_field("contents_content_#{key}values_value_es", with: 'Título') end - scenario "Select a locale and add it to the milestone form", :js do + scenario "Select a locale and add it to the form", :js do key = "debates.form.debate_title" visit admin_site_customization_information_texts_path From 8015596cb8a99b2ea96d94f0fb86d632b83e3812 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 19:39:49 -0400 Subject: [PATCH 50/85] Replace hardcoded update notice when updating translations with proper I18n --- .../admin/site_customization/information_texts_controller.rb | 3 ++- config/locales/en/responders.yml | 1 + config/locales/es/responders.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 8a523f989..5227b3a78 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -27,7 +27,8 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz end - redirect_to admin_site_customization_information_texts_path, notice: "Translation updated successfully" + redirect_to admin_site_customization_information_texts_path, + notice: t('flash.actions.update.translation') end private diff --git a/config/locales/en/responders.yml b/config/locales/en/responders.yml index f91cb807c..e11b071f2 100644 --- a/config/locales/en/responders.yml +++ b/config/locales/en/responders.yml @@ -29,6 +29,7 @@ en: budget_investment: "Investment project updated succesfully." topic: "Topic updated successfully." valuator_group: "Valuator group updated successfully" + translation: "Translation updated successfully" destroy: spending_proposal: "Spending proposal deleted succesfully." budget_investment: "Investment project deleted succesfully." diff --git a/config/locales/es/responders.yml b/config/locales/es/responders.yml index 3674a0290..1910acd95 100644 --- a/config/locales/es/responders.yml +++ b/config/locales/es/responders.yml @@ -29,6 +29,7 @@ es: budget_investment: "Proyecto de gasto actualizado correctamente" topic: "Tema actualizado correctamente." valuator_group: "Grupo de evaluadores actualizado correctamente" + translation: "Traducción actualizada correctamente" destroy: spending_proposal: "Propuesta de inversión eliminada." budget_investment: "Proyecto de gasto eliminado." From a943c24aa795f6010c8a6ab2249a39b5a628d14f Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 21:13:53 -0400 Subject: [PATCH 51/85] Replace Madrid-specific texts with CONSUL ones --- .../admin/site_customization/information_texts_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index ddfb11021..b5ed5496b 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -11,7 +11,7 @@ feature "Admin custom information texts" do visit admin_site_customization_information_texts_path click_link 'Debates' - expect(page).to have_content 'Help about citizen debates' + expect(page).to have_content 'Help about debates' click_link 'Community' expect(page).to have_content 'Access the community' @@ -41,7 +41,7 @@ feature "Admin custom information texts" do expect(page).to have_content 'Choose what you want to create' click_link 'Welcome' - expect(page).to have_content 'See all recommended debates' + expect(page).to have_content 'See all debates' end context "Globalization" do From 12f6f06ade07ba33f4d9d0ee9e453a2b66cc6948 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 27 Jul 2018 01:50:51 +0200 Subject: [PATCH 52/85] Fix exception when using locale as a parameter in the url When visiting, for example, /admin/site_customization/information_texts?locale=fr we were getting an `UncaughtThrowError: uncaught throw :exception` With the following payload ``` File "/aytomad/app/participa/participacion/releases/20180726231929/app/views/admin/site_customization/information_texts/_form_field.html.erb" line 5 File "/aytomad/app/participa/participacion/releases/20180726231929/app/helpers/globalize_helper.rb" line 35 in block in globalize ``` Substituting this line seems to solve it Note that we had to remove the portuguese local too, as it was giving a different exception due to this change. This problem, has been solved in the original globalization PR --- app/models/i18n_content.rb | 2 +- .../site_customization/information_texts/_form_field.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb index d7914c83a..8d130539b 100644 --- a/app/models/i18n_content.rb +++ b/app/models/i18n_content.rb @@ -6,6 +6,6 @@ class I18nContent < ActiveRecord::Base validates :key, uniqueness: true translates :value, touch: true - globalize_accessors locales: [:en, :es, :fr, :nl, :val, :pt_br] + globalize_accessors locales: [:en, :es, :fr, :nl, :val] end diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index 4ae31adec..09227feaf 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -2,7 +2,7 @@ <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", I18nContent.where(key: content.key).first.try(:value) || - I18n.backend.translate(locale, content.key), + t(content.key, locale: locale), { rows: 5, class: "js-globalize-attribute", style: display_translation?(locale), From 4c8b174274b8a229e7d138607770bea55da5a3d3 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 27 Jul 2018 03:01:38 +0200 Subject: [PATCH 53/85] Display only translations for the current language After creating a translation in spanish, it was also displaying it when selecting the english locale. This was due to the code picking the first translation available With this commit, we are checking for an existing translation in the current locale and displaying it if it exists --- .../information_texts_controller.rb | 2 +- app/models/i18n_content.rb | 1 - .../information_texts/_form_field.html.erb | 10 +++++++++- config/initializers/i18n_translation.rb | 19 +++++++------------ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 5227b3a78..54739e8f3 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -15,7 +15,7 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz values.each do |key, value| locale = key.split("_").last - if value == I18n.backend.translate(locale, content[:id]) + if value == t(content[:id], locale: locale) next else text = I18nContent.find_or_create_by(key: content[:id]) diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb index 8d130539b..239894856 100644 --- a/app/models/i18n_content.rb +++ b/app/models/i18n_content.rb @@ -7,5 +7,4 @@ class I18nContent < ActiveRecord::Base translates :value, touch: true globalize_accessors locales: [:en, :es, :fr, :nl, :val] - end diff --git a/app/views/admin/site_customization/information_texts/_form_field.html.erb b/app/views/admin/site_customization/information_texts/_form_field.html.erb index 09227feaf..54945dfb6 100644 --- a/app/views/admin/site_customization/information_texts/_form_field.html.erb +++ b/app/views/admin/site_customization/information_texts/_form_field.html.erb @@ -1,7 +1,15 @@ <% globalize(locale) do %> + + <% i18n_content = I18nContent.where(key: content.key).first %> + <% if i18n_content.present? %> + <% i18n_content_translation = I18nContentTranslation.where(i18n_content_id: i18n_content.id, locale: locale).first.try(:value) %> + <% else %> + <% i18n_content_translation = false %> + <% end %> + <%= hidden_field_tag "contents[content_#{content.key}][id]", content.key %> <%= text_area_tag "contents[content_#{content.key}]values[value_#{locale}]", - I18nContent.where(key: content.key).first.try(:value) || + i18n_content_translation || t(content.key, locale: locale), { rows: 5, class: "js-globalize-attribute", diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb index 9c7ad66da..c01199a08 100644 --- a/config/initializers/i18n_translation.rb +++ b/config/initializers/i18n_translation.rb @@ -7,21 +7,16 @@ module ActionView include TagHelper def t(key, options = {}) - translation = I18nContent.by_key(key) + current_locale = options[:locale].present? ? options[:locale] : I18n.locale + i18_content = I18nContent.by_key(key).first + translation = I18nContentTranslation.where(i18n_content_id: i18_content&.id, + locale: current_locale).first&.value if translation.present? - Globalize.with_locale(locale) do - string = translation.first.value - - options.each do |key, value| - string.sub! "%{#{key}}", (value || "%{#{key}}") - end - - return string.html_safe unless string.nil? - end + translation + else + translate(key, options) end - - translate(key, options) end end end From ea4f07958824a45a652f31f3607b4e5b40dad94f Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 27 Jul 2018 03:19:01 +0200 Subject: [PATCH 54/85] Do not store missing translations in DB When visiting http://localhost:3000/admin/site_customization/information_texts?locale=fr and creating a translation, other languages where storing translations in db with the following values: "One"> With this commit we are not storing this translations Note that this only happened when using a param[:locale] in the url at least for french --- .../admin/site_customization/information_texts_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/site_customization/information_texts_controller.rb b/app/controllers/admin/site_customization/information_texts_controller.rb index 54739e8f3..25594fc4a 100644 --- a/app/controllers/admin/site_customization/information_texts_controller.rb +++ b/app/controllers/admin/site_customization/information_texts_controller.rb @@ -15,7 +15,7 @@ class Admin::SiteCustomization::InformationTextsController < Admin::SiteCustomiz values.each do |key, value| locale = key.split("_").last - if value == t(content[:id], locale: locale) + if value == t(content[:id], locale: locale) || value.match(/translation missing/) next else text = I18nContent.find_or_create_by(key: content[:id]) From 57dbb0220a257557bb0f484b6719c06e2e67fd6d Mon Sep 17 00:00:00 2001 From: 16yuki0702 Date: Fri, 27 Jul 2018 15:45:42 +0900 Subject: [PATCH 55/85] Fix active item on admin menu --- app/helpers/admin_helper.rb | 4 ++-- app/views/admin/_menu.html.erb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 988d03a00..24cce7945 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -21,11 +21,11 @@ module AdminHelper end def menu_polls? - %w[polls questions answers].include?(controller_name) + %w[polls questions answers booth_assignments officer_assignments recounts results].include?(controller_name) end def menu_booths? - %w[officers booths officer_assignments booth_assignments recounts results shifts].include?(controller_name) + %w[officers booths shifts].include?(controller_name) end def menu_profiles? diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index ffec03232..49c204c30 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -7,7 +7,7 @@ <%= t("admin.menu.title_polls") %>
              > -
            • > +
            • > <%= link_to t("admin.menu.polls"), admin_polls_path %>
            • @@ -40,7 +40,7 @@
            • > + %w(available new).include?(action_name) %>> <%= link_to t("admin.menu.poll_shifts"), available_admin_booths_path %>
            @@ -110,7 +110,7 @@
              > -
            • > +
            • > <%= link_to t("admin.menu.site_customization.homepage"), admin_homepage_path %>
            • From c14fbf85405b5ebcfe8b53d2188ee72e6e5f7e97 Mon Sep 17 00:00:00 2001 From: 16yuki0702 Date: Fri, 27 Jul 2018 16:34:00 +0900 Subject: [PATCH 56/85] Fixed misunderstanding --- app/helpers/admin_helper.rb | 4 ++-- app/views/admin/_menu.html.erb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 24cce7945..2c1a32c70 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -21,11 +21,11 @@ module AdminHelper end def menu_polls? - %w[polls questions answers booth_assignments officer_assignments recounts results].include?(controller_name) + %w[polls questions answers recounts results].include?(controller_name) end def menu_booths? - %w[officers booths shifts].include?(controller_name) + %w[officers booths shifts booth_assignments officer_assignments].include?(controller_name) end def menu_profiles? diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 49c204c30..78ce6b351 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -7,7 +7,7 @@ <%= t("admin.menu.title_polls") %>
                > -
              • > +
              • > <%= link_to t("admin.menu.polls"), admin_polls_path %>
              • @@ -25,7 +25,7 @@ <%= t("admin.menu.title_booths") %>
                  > -
                • > +
                • > <%= link_to t("admin.menu.poll_officers"), admin_officers_path %>
                • @@ -35,7 +35,7 @@
                • > + controller_name == "booth_assignments" %>> <%= link_to t("admin.menu.poll_booth_assignments"), booth_assignments_admin_polls_path %>
                • From 29957347625a704af385ea2e7c0fb29190b72253 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 5 Jul 2018 15:39:38 +0200 Subject: [PATCH 57/85] Increase max cache size to 2MB We have lots of votes in this edition of participatory budgets and the default cache size (1MB) is not enough to hold certain cache fragments --- config/environments/preproduction.rb | 2 +- config/environments/production.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/environments/preproduction.rb b/config/environments/preproduction.rb index 692b90c51..3750a21d0 100644 --- a/config/environments/preproduction.rb +++ b/config/environments/preproduction.rb @@ -55,7 +55,7 @@ Rails.application.configure do # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production. - config.cache_store = :dalli_store + config.cache_store = :dalli_store, { value_max_bytes: 2000000 } # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.action_controller.asset_host = 'http://assets.example.com' diff --git a/config/environments/production.rb b/config/environments/production.rb index 9ca195dd7..60ab4fdf3 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -55,7 +55,7 @@ Rails.application.configure do # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production. - config.cache_store = :dalli_store + config.cache_store = :dalli_store, { value_max_bytes: 2000000 } # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.action_controller.asset_host = 'http://assets.example.com' From 5d03fd210c3503c11486b64cc0755a79927630b6 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 26 Jul 2018 22:39:15 -0400 Subject: [PATCH 58/85] Remove Valencian language key to fix translations spec --- app/models/i18n_content.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb index 239894856..c291e696c 100644 --- a/app/models/i18n_content.rb +++ b/app/models/i18n_content.rb @@ -6,5 +6,6 @@ class I18nContent < ActiveRecord::Base validates :key, uniqueness: true translates :value, touch: true - globalize_accessors locales: [:en, :es, :fr, :nl, :val] + globalize_accessors locales: [:en, :es, :fr, :nl] + end From 2543cf5d6cc9a1858df80c68b1dd2dfccad3430f Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 30 Jul 2018 17:45:19 +0200 Subject: [PATCH 59/85] Removes custom content on help pages --- app/views/pages/census_terms.html.erb | 1 - app/views/pages/help/_budgets.html.erb | 12 ------------ app/views/pages/help/_polls.html.erb | 2 -- app/views/pages/help/_processes.html.erb | 3 --- app/views/pages/help/_proposals.html.erb | 7 ------- app/views/pages/help/index.html.erb | 1 - config/locales/en/pages.yml | 15 +-------------- config/locales/es/pages.yml | 13 +------------ 8 files changed, 2 insertions(+), 52 deletions(-) diff --git a/app/views/pages/census_terms.html.erb b/app/views/pages/census_terms.html.erb index 4134e33b7..df5797450 100644 --- a/app/views/pages/census_terms.html.erb +++ b/app/views/pages/census_terms.html.erb @@ -6,7 +6,6 @@

                  Terminos de acceso al Padrón

                  - <%= simple_format t('pages.census_terms') %>
                  diff --git a/app/views/pages/help/_budgets.html.erb b/app/views/pages/help/_budgets.html.erb index 1e6cd251d..116bb0deb 100644 --- a/app/views/pages/help/_budgets.html.erb +++ b/app/views/pages/help/_budgets.html.erb @@ -7,18 +7,6 @@ <%= t("pages.help.budgets.description", link: link_to(t("pages.help.budgets.link"), budgets_path)).html_safe %>

                  -
                    -
                  • - <%= t("pages.help.budgets.feature") %> -
                  • -
                  • <%= t("pages.help.budgets.phase_1_html", - org: setting['org_name']).html_safe %>
                  • -
                  • <%= t("pages.help.budgets.phase_2_html") %>
                  • -
                  • <%= t("pages.help.budgets.phase_3_html") %>
                  • -
                  • <%= t("pages.help.budgets.phase_4_html") %>
                  • -
                  - -

                  <%= t("pages.help.budgets.phase_5_html") %>

                  <%= image_tag "help/budgets_#{I18n.locale}.png", alt: t("pages.help.budgets.image_alt") %> diff --git a/app/views/pages/help/_polls.html.erb b/app/views/pages/help/_polls.html.erb index 64a7d23f2..1605169b9 100644 --- a/app/views/pages/help/_polls.html.erb +++ b/app/views/pages/help/_polls.html.erb @@ -11,8 +11,6 @@ link: link_to(t("pages.help.polls.feature_1_link", org_name: setting['org_name']), new_user_registration_path)).html_safe %> -
                • <%= t("pages.help.polls.feature_2") %>
                • -
                • <%= t("pages.help.polls.feature_3") %>
                diff --git a/app/views/pages/help/_processes.html.erb b/app/views/pages/help/_processes.html.erb index f1be22747..abe64f4ab 100644 --- a/app/views/pages/help/_processes.html.erb +++ b/app/views/pages/help/_processes.html.erb @@ -11,9 +11,6 @@
                • <% link = link_to(t("pages.help.processes.link"), legislation_processes_path) %> - <% sign_up_link = t("pages.help.processes.sign_up", org: setting['org_name']) %> - <% sign_up = link_to(sign_up_link, new_user_registration_path) %> - <%= t("pages.help.processes.feature", link: link, sign_up: sign_up).html_safe %>
                diff --git a/app/views/pages/help/_proposals.html.erb b/app/views/pages/help/_proposals.html.erb index c8333b5fd..6cc932242 100644 --- a/app/views/pages/help/_proposals.html.erb +++ b/app/views/pages/help/_proposals.html.erb @@ -7,13 +7,6 @@ <%= t("pages.help.proposals.description", link: link_to(t("pages.help.proposals.link"), proposals_path)).html_safe %>

                -
                  -
                • - <%= t("pages.help.proposals.feature_html", - org: setting['org_name'], - supports: setting['votes_for_proposal_success']).html_safe %> -
                • -
                <%= image_tag "help/proposals_#{I18n.locale}.png", alt: t("pages.help.proposals.image_alt") %> diff --git a/app/views/pages/help/index.html.erb b/app/views/pages/help/index.html.erb index e0e268f7e..fd989c23d 100644 --- a/app/views/pages/help/index.html.erb +++ b/app/views/pages/help/index.html.erb @@ -11,7 +11,6 @@

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

                -

                <%= t("pages.help.subtitle", org: setting['org_name']) %>

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

                diff --git a/config/locales/en/pages.yml b/config/locales/en/pages.yml index 1e4eb616b..fcc1dafec 100644 --- a/config/locales/en/pages.yml +++ b/config/locales/en/pages.yml @@ -1,11 +1,9 @@ en: pages: - census_terms: To confirm the account, you must be 16 or older and be registered, having provided the information requested previously, will verify. By accepting the verification process, you also consent to the verification of this information, as well as the contact methods featuring in said files. The data provided will be acquired and processed in a file mentioned previously in the terms and conditions of use for the Portal. conditions: Terms and conditions of use general_terms: Terms and Conditions help: title: "%{org} is a platform for citizen participation" - subtitle: "In %{org} you can make proposals, vote in citizen consultations, propose participatory budget projects, decide on municipal regulations and open debates to exchange opinions with others." guide: "This guide explains what each of the %{org} sections are for and how they work." menu: debates: "Debates" @@ -26,19 +24,12 @@ en: title: "Proposals" description: "In the %{link} section you can make proposals for the City Council to carry them out. The proposals require support, and if they reach sufficient support, they are put to a public vote. The proposals approved in these citizens' votes are accepted by the City Council and carried out." link: "citizen proposals" - feature_html: "To create a proposal you must register in %{org}. The proposals that get the support on the website of 1% of people with the right to vote (%{supports} supports of people over 16 years old registered) go to vote. To support proposals it is necessary to verify your account." image_alt: "Button to support a proposal" - figcaption_html: 'Button to "Support" a proposal.
                When it reaches the number of supports will go to vote.' + figcaption_html: 'Button to "Support" a proposal.' budgets: title: "Participatory Budgeting" description: "The %{link} section helps people make a direct decision on what part of the municipal budget is spent on." link: "participative budgets" - feature: "In this process, every year people raise, support and vote on projects. The most voted votes are financed by the municipal budget." - phase_1_html: "Between January and early March, people registered in %{org} can present." - phase_2_html: "In March, proposers have to gather support, in the form of preselection." - phase_3_html: "Between April and the beginning of May, the experts from the City Council rate projects on an order of more or less supported and check that they are viable." - phase_4_html: "Finally, between May and June, all citizens can vote projects that interest them the most." - phase_5_html: "From the approval of the budgets the following year the City Council begins to carry out the winning projects." image_alt: "Different phases of a participatory budget" figcaption_html: '"Support" and "Voting" phases of participatory budgets.' polls: @@ -47,14 +38,10 @@ en: link: "polls" feature_1: "To participate in the voting you have to %{link} and verify your account." feature_1_link: "register in %{org_name}" - feature_2: "All registered voters over the age of 16 can vote." - feature_3: "The results of all votes are binding on the municipal government." processes: title: "Processes" description: "In the %{link} section, citizens participate in the drafting and modification of regulations affecting the city and can give their opinion on municipal policies in previous debates." link: "processes" - feature: "To participate in a process you have to %{sign_up} and check the %{link} page periodically to see which regulations and policies are being discussed and consulted." - sign_up: "sign up on %{org}" faq: title: "Technical problems?" description: "Read the FAQs and solve your questions." diff --git a/config/locales/es/pages.yml b/config/locales/es/pages.yml index 76808faf6..81d66a5ad 100644 --- a/config/locales/es/pages.yml +++ b/config/locales/es/pages.yml @@ -1,11 +1,9 @@ es: pages: - census_terms: Para verificar la cuenta hay que tener 16 años o más y estar empadronado aportando los datos indicados anteriormente, los cuales serán contrastados. Aceptando el proceso de verificación acepta dar su consentimiento para contrastar dicha información, así como medios de contacto que figuren en dichos ficheros. Los datos aportados serán incorporados y tratados en un fichero indicado anteriormente en las condiciones de uso del portal. conditions: Condiciones de uso general_terms: Términos y Condiciones help: title: "%{org} es una plataforma de participación ciudadana" - subtitle: "En %{org} se pueden hacer propuestas, votar en consultas ciudadanas, plantear proyectos de presupuestos participativos, decidir la normativa municipal y abrir debates para intercambiar opiniones con otras personas." guide: 'Esta guía explica para qué sirven y cómo funcionan cada una de las secciones de %{org}.' menu: debates: "Debates" @@ -26,19 +24,12 @@ es: title: "Propuestas" description: "En la sección de %{link} puedes plantear propuestas para que el Ayuntamiento las lleve a cabo. Las propuestas recaban apoyos, y si alcanzan los apoyos suficientes se someten a votación ciudadana. Las propuestas aprobadas en estas votaciones ciudadanas son asumidas por el Ayuntamiento y se llevan a cabo." link: "propuestas ciudadanas" - feature_html: "Para crear una propuesta hay que registrarse en %{org}. Las propuestas que consiguen el apoyo en la web del 1% de la gente con derecho a voto (%{supports} apoyos de personas mayores de 16 años empadronadas) pasan a votación. Para apoyar propuestas es necesario verificar tu cuenta." image_alt: "Botón para apoyar una propuesta" - figcaption_html: 'Botón para "Apoyar" una propuesta.
                Cuando alcance el número de apoyos pasará a votación.' + figcaption_html: 'Botón para "Apoyar" una propuesta.' budgets: title: "Presupuestos participativos" description: "La sección de %{link} sirve para que la gente decida de manera directa a qué se destina una parte del presupuesto municipal." link: "presupuestos participativos" - feature: "En este proceso cada año la gente plantea, apoya y vota proyectos. Los más votados pasan a financiarse con el presupuesto municipal." - phase_1_html: "Entre enero y principios de marzo, las personas registradas en %{org} pueden presentar proyectos." - phase_2_html: "En marzo, los proponentes tienen que recabar apoyos, a modo de fase de preselección." - phase_3_html: "Entre abril y comienzos de mayo los técnicos del Ayuntamiento tasan los proyectos por orden de más a menos apoyados y comprueban que son viables." - phase_4_html: "Finalmente, entre mayo y junio, toda la ciudadanía puede votar los proyectos que más le interesan." - phase_5_html: "A partir de la aprobación de los presupuestos al año siguiente el Ayuntamiento empieza a llevar a cabo los proyectos ganadores." image_alt: "Diferentes fases de un presupuesto participativo" figcaption_html: 'Fase de "Apoyos" y fase de "Votación" de los presupuestos participativos.' polls: @@ -47,8 +38,6 @@ es: link: "votaciones ciudadanas" feature_1: "Para participar en las votaciones tienes que %{link} y verificar tu cuenta." feature_1_link: "registrarte en %{org_name}" - feature_2: "Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años." - feature_3: "Los resultados de todas las votaciones son vinculantes para el gobierno municipal." processes: title: "Procesos legislativos" description: "En la sección de %{link} la ciudadanía participa en la elaboración y modificación de normativa que afecta a la ciudad y puede dar su opinión sobre las políticas municipales en debates previos." From 52fa9d27acd1e977d21eeddcb8eaf88035d9e372 Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 30 Jul 2018 17:55:56 +0200 Subject: [PATCH 60/85] Removes custom content on index views pages --- app/views/budgets/index.html.erb | 5 ----- app/views/debates/index.html.erb | 3 --- app/views/legislation/processes/index.html.erb | 4 ---- app/views/polls/index.html.erb | 3 --- app/views/proposals/index.html.erb | 5 ----- config/locales/en/budgets.yml | 6 +----- config/locales/en/general.yml | 12 ++---------- config/locales/en/legislation.yml | 3 --- config/locales/es/budgets.yml | 6 +----- config/locales/es/general.yml | 12 ++---------- config/locales/es/legislation.yml | 3 --- 11 files changed, 6 insertions(+), 56 deletions(-) diff --git a/app/views/budgets/index.html.erb b/app/views/budgets/index.html.erb index 08efd5236..9d73bf571 100644 --- a/app/views/budgets/index.html.erb +++ b/app/views/budgets/index.html.erb @@ -183,11 +183,6 @@ <%= t("budgets.index.section_footer.title") %>

                <%= t("budgets.index.section_footer.description") %>

                -

                <%= t("budgets.index.section_footer.help_text_1") %>

                -

                <%= t("budgets.index.section_footer.help_text_2") %>

                -

                <%= t("budgets.index.section_footer.help_text_3", - org: link_to(setting['org_name'], new_user_registration_path)).html_safe %>

                -

                <%= t("budgets.index.section_footer.help_text_4") %>

                diff --git a/app/views/debates/index.html.erb b/app/views/debates/index.html.erb index 967864f04..2da6eb1bc 100644 --- a/app/views/debates/index.html.erb +++ b/app/views/debates/index.html.erb @@ -88,9 +88,6 @@

                <%= t("debates.index.section_footer.help_text_1") %>

                <%= t("debates.index.section_footer.help_text_2", org: link_to(setting["org_name"], new_user_registration_path)).html_safe %>

                -

                <%= t("debates.index.section_footer.help_text_3", - proposal: link_to(t("debates.index.section_footer.proposals_link"), proposals_path), - budget: link_to(t("debates.index.section_footer.budget_link"), budgets_path)).html_safe %>

                <% end %> diff --git a/app/views/legislation/processes/index.html.erb b/app/views/legislation/processes/index.html.erb index 7630d29ac..4e4421b18 100644 --- a/app/views/legislation/processes/index.html.erb +++ b/app/views/legislation/processes/index.html.erb @@ -24,10 +24,6 @@ <%= t("legislation.processes.index.section_footer.title") %>

                <%= t("legislation.processes.index.section_footer.description") %>

                -

                <%= t("legislation.processes.index.section_footer.help_text_1") %>

                -

                <%= t("legislation.processes.index.section_footer.help_text_2", - org: setting['org_name']) %>

                -

                <%= t("legislation.processes.index.section_footer.help_text_3") %>

                diff --git a/app/views/polls/index.html.erb b/app/views/polls/index.html.erb index 7f905491f..9a512ec93 100644 --- a/app/views/polls/index.html.erb +++ b/app/views/polls/index.html.erb @@ -38,9 +38,6 @@ <%= t("polls.index.section_footer.title") %>

                <%= t("polls.index.section_footer.description") %>

                -

                <%= t("polls.index.section_footer.help_text_1") %>

                -

                <%= t("polls.index.section_footer.help_text_2", - org: link_to(setting['org_name'], new_user_registration_path)).html_safe %>

                diff --git a/app/views/proposals/index.html.erb b/app/views/proposals/index.html.erb index 25c294654..2217513f8 100644 --- a/app/views/proposals/index.html.erb +++ b/app/views/proposals/index.html.erb @@ -101,11 +101,6 @@ <%= t("proposals.index.section_footer.title") %>

                <%= t("proposals.index.section_footer.description") %>

                -

                <%= t("proposals.index.section_footer.help_text_1") %>

                -

                <%= t("proposals.index.section_footer.help_text_2", - org: link_to(setting['org_name'], new_user_registration_path), - supports: setting["votes_for_proposal_success"]).html_safe %>

                -

                <%= t("proposals.index.section_footer.help_text_3") %>

                <% end %> diff --git a/config/locales/en/budgets.yml b/config/locales/en/budgets.yml index 8418dc65f..094fcbe9e 100644 --- a/config/locales/en/budgets.yml +++ b/config/locales/en/budgets.yml @@ -56,11 +56,7 @@ en: see_results: See results section_footer: title: Help with participatory budgets - description: With the participatory budgets the citizens decide to which projects presented by the neighbors is destined a part of the municipal budget. - help_text_1: "Participatory budgets are processes in which citizens decide directly on what is spent part of the municipal budget. Any registered person over 16 years old can propose an investment project that is preselected in a phase of citizen supports." - help_text_2: "The most voted projects are evaluated and passed to a final vote in which they decide the actions to be carried out by the City Council once the municipal budgets of the next year are approved." - help_text_3: "The presentation of participatory budgeting projects takes place from January and over a period of one and a half months. To participate and propose proposals for the entire city and / or districts, you must sign up on %{org} and verify your account." - help_text_4: "To get as many supports and votes as possible, choose a descriptive and understandable headline for your project. Then you have a space to develop the approach of your proposal. Provide all the data and explanations, and even documents and images, to help other participants to better understand what you are proposing." + description: With the participatory budgets the citizens decide to which projects is destined a part of the budget. investments: form: tag_category_label: "Categories" diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index a3a451c2a..c2d89b06e 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -136,9 +136,6 @@ en: description: Start a debate to share opinions with others about the topics you are concerned about. help_text_1: "The space for citizen debates is aimed at anyone who can expose issues of their concern and those who want to share opinions with other people." help_text_2: 'To open a debate you need to sign up on %{org}. Users can also comment on open debates and rate them with the "I agree" or "I disagree" buttons found in each of them.' - help_text_3: "Keep in mind that a debate does not start any specific action. If you want to make a %{proposal} for the city or raise a investment project of %{budget} when the phase is open, go to the corresponding section." - proposals_link: proposal - budget_link: participatory budgeting new: form: submit_button: Start a debate @@ -400,10 +397,7 @@ en: help: Help about proposals section_footer: title: Help about proposals - description: Make a citizen proposal. If it gets enough supports it will go to voting phase, so you can get all the citizens to decide how they want their city to be. - help_text_1: "The citizen proposals are an opportunity for neighbours and collectives to decide directly how they want to shape their city. Any person can make a proposal about a topic or concern of their interest, for the City Council to make it, after it gets enough supports to be put to a citizens vote." - help_text_2: "To create a proposal, you must sign up on %{org}. The proposals that get the support of 1% of the users in the web, goes to voting phase. To support proposals it is necessary to have a verified account." - help_text_3: "A citizen vote is celebrated when the proposals get the necessary supports. Once celebrated, if there are more people in favor than against, the City Council assumes the proposal and carries it out." + description: Citizens' proposals are an opportunity for neighbours and collectives to decide directly how they want their city to be, after getting sufficient support and submitting to a citizens' vote. new: form: submit_button: Create proposal @@ -493,9 +487,7 @@ en: help: Help about voting section_footer: title: Help about voting - description: Sign up to vote on citizen proposals and questions the City Council ask to the neighbors. Make municipal decisions directly. - help_text_1: "Voting takes place when a citizen proposal supports reaches 1% of the census with voting rights. Voting can also include questions that the City Council ask to the citizens decision." - help_text_2: "To participate in the next vote you have to sign up on %{org} and verify your account. All registered voters in the city over 16 years old can vote. The results of all votes are binding on the government." + description: Citizens' polls are a participatory mechanism by which citizens with voting rights can make direct decisions no_polls: "There are no open votings." show: already_voted_in_booth: "You have already participated in a physical booth. You can not participate again." diff --git a/config/locales/en/legislation.yml b/config/locales/en/legislation.yml index b0f387997..9553f73aa 100644 --- a/config/locales/en/legislation.yml +++ b/config/locales/en/legislation.yml @@ -71,9 +71,6 @@ en: section_footer: title: Help about legislation processes description: Participate in the debates and processes prior to the approval of a ordinance or a municipal action. Your opinion will be considered by the City Council. - help_text_1: "In participatory processes, the City Council offers to its citizens the opportunity to participate in the drafting and modification of regulations, affecting the city and to be able to give their opinion on certain actions that it plans to carry out." - help_text_2: "People registered in %{org} can participate with contributions in the public consultation of new ordinances, regulations and guidelines, among others. Your comments are analyzed by the corresponding area and considered for the final drafting of the ordinances." - help_text_3: "The City Council also opens processes to receive contributions and opinions on municipal actions." phase_not_open: not_open: This phase is not open yet phase_empty: diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index 14df02fea..b2cae1dbf 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -56,11 +56,7 @@ es: see_results: Ver resultados section_footer: title: Ayuda sobre presupuestos participativos - description: Con los presupuestos participativos la ciudadanía decide a qué proyectos presentados por los vecinos y vecinas va destinada una parte del presupuesto municipal. - help_text_1: "Los presupuestos participativos son unos procesos en los que la ciudadanía decide de forma directa en qué se gasta una parte del presupuesto municipal. Cualquier persona empadronada mayor de 16 años puede proponer un proyecto de gasto que se preselecciona en una fase de apoyos ciudadanos." - help_text_2: "Los proyectos más votados se evalúan y pasan a una votación final en la que se deciden las actuaciones que llevará a cabo el Ayuntamiento una vez se aprueben los presupuestos municipales del año próximo." - help_text_3: "La presentación de proyectos de presupuestos participativos se lleva a cabo desde enero y a lo largo de un periodo de mes y medio, aproximadamente. Para participar y plantear propuestas para toda la ciudad y/ los distritos hay que registrarse en %{org} y verificar la cuenta." - help_text_4: "Para conseguir el mayor número de apoyos y votos posible, elige un titular descriptivo y comprensible de tu proyecto. Después tienes un espacio para desarrollar el planteamiento de tu propuesta. Aporta todos los datos y explicaciones, e incluso documentos e imágenes, para ayudar a otras personas participantes a entender mejor lo que planteas." + description: Con los presupuestos participativos la ciudadanía decide a qué proyectos va destinada una parte del presupuesto. investments: form: tag_category_label: "Categorías" diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 69f49c18a..6451d21b0 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -136,9 +136,6 @@ es: description: Inicia un debate para compartir puntos de vista con otras personas sobre los temas que te preocupan. help_text_1: "El espacio de debates ciudadanos está dirigido a que cualquier persona pueda exponer temas que le preocupan y sobre los que quiera compartir puntos de vista con otras personas." help_text_2: 'Para abrir un debate es necesario registrarse en %{org}. Los usuarios ya registrados también pueden comentar los debates abiertos y valorarlos con los botones de "Estoy de acuerdo" o "No estoy de acuerdo" que se encuentran en cada uno de ellos.' - help_text_3: "Ten en cuenta que un debate no activa ningún mecanismo de actuación concreto. Si quieres hacer una %{proposal} para la ciudad o plantear un proyecto de %{budget} cuando se abra la convocatoria, ve a la sección correspondiente." - proposals_link: propuesta - budget_link: presupuestos participativos new: form: submit_button: Empieza un debate @@ -400,10 +397,7 @@ es: help: Ayuda sobre las propuestas section_footer: title: Ayuda sobre las propuestas - description: Haz una propuesta ciudadana. Si obtiene los apoyos suficientes y pasa a votación, puedes conseguir que todos los habitantes decidan cómo quieren que sea nuestra ciudad. - help_text_1: "Las propuestas ciudadanas son una oportunidad para que los vecinos y colectivos decidan directamente cómo quieren que sea su ciudad. Cualquier persona puede hacer una propuesta sobre un tema que le interese o preocupe para que el ayuntamiento la lleve a cabo, después de conseguir los apoyos suficientes y de someterse a votación ciudadana." - help_text_2: "Para crear una propuesta hay que registrarse en %{org}. Las propuestas que consigan el apoyo del 1% de la gente en la web, pasan a votación. Para apoyar propuestas es necesario tener una cuenta verificada." - help_text_3: "Se convoca una votación ciudadana cuando las propuestas consiguen los apoyos necesarios. Una vez celebrada, si hay más gente a favor que en contra, el Consistorio asume la propuesta y la lleva a cabo." + description: Las propuestas ciudadanas son una oportunidad para que los vecinos y colectivos decidan directamente cómo quieren que sea su ciudad, después de conseguir los apoyos suficientes y de someterse a votación ciudadana. new: form: submit_button: Crear propuesta @@ -493,9 +487,7 @@ es: help: Ayuda sobre las votaciones section_footer: title: Ayuda sobre las votaciones - description: Regístrate para poder votar propuestas ciudadanas y las cuestiones que pregunta a sus vecinos el Ayuntamiento. Toma decisiones municipales de forma directa. - help_text_1: "Las votaciones se convocan cuando una propuesta ciudadana alcanza el 1% de apoyos del censo con derecho a voto. En las votaciones también se pueden incluir cuestiones que el Ayuntamiento somete a decisión directa de la ciudadanía." - help_text_2: "Para participar en la próxima votación tienes que registrarte en %{org} y verificar tu cuenta. Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años. Los resultados de todas las votaciones serán vinculantes para el gobierno." + description: Las votaciones ciudadanas son un mecanismo de participación por el que la ciudadanía con derecho a voto puede tomar decisiones de forma directa. no_polls: "No hay votaciones abiertas." show: already_voted_in_booth: "Ya has participado en esta votación en urnas presenciales, no puedes volver a participar." diff --git a/config/locales/es/legislation.yml b/config/locales/es/legislation.yml index e4654f6a6..dd6f95a35 100644 --- a/config/locales/es/legislation.yml +++ b/config/locales/es/legislation.yml @@ -71,9 +71,6 @@ es: section_footer: title: Ayuda sobre procesos legislativos description: Participa en los debates y procesos previos a la aprobación de una norma o de una actuación municipal. Tu opinión será tenida en cuenta por el Ayuntamiento. - help_text_1: "En los procesos participativos, el Ayuntamiento ofrece a la ciudadanía la oportunidad de participar en la elaboración y modificación de normativa que afecta a la ciudad y de dar su opinión sobre ciertas actuaciones que tiene previsto llevar a cabo." - help_text_2: "Las personas registradas en %{org} pueden participar con aportaciones en la consulta pública de nuevas ordenanzas, reglamentos y directrices, entre otros. Sus comentarios son analizados por el área correspondiente y tenidos en cuenta de cara a la redacción final de las normas." - help_text_3: "El Ayuntamiento también abre procesos para recibir aportaciones y opiniones sobre actuaciones municipales." phase_not_open: not_open: Esta fase del proceso todavía no está abierta phase_empty: From 62343ba49b6d7de339257874f1a6554bed2db52f Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 30 Jul 2018 17:56:23 +0200 Subject: [PATCH 61/85] Removes custom content on top links --- app/views/shared/_top_links.html.erb | 15 --------------- config/locales/en/general.yml | 4 ---- config/locales/es/general.yml | 4 ---- 3 files changed, 23 deletions(-) diff --git a/app/views/shared/_top_links.html.erb b/app/views/shared/_top_links.html.erb index 88b7f7dfe..5db6edab5 100644 --- a/app/views/shared/_top_links.html.erb +++ b/app/views/shared/_top_links.html.erb @@ -1,19 +1,4 @@