From ff1fced6099bd0379d096e0da96a2f55e6645516 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Wed, 28 Mar 2018 10:14:57 -0400 Subject: [PATCH 001/341] 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 002/341] 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 003/341] 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 004/341] 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 452d7dd252eb334aa0102a312d7b2407990a2868 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 19 Jun 2018 11:03:45 -0400 Subject: [PATCH 005/341] Fix page entries information and filter positioning --- app/views/moderation/comments/index.html.erb | 12 ++++-------- app/views/moderation/debates/index.html.erb | 12 ++++-------- app/views/moderation/proposals/index.html.erb | 12 ++++-------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/app/views/moderation/comments/index.html.erb b/app/views/moderation/comments/index.html.erb index e391d9e5e..ae919a71c 100644 --- a/app/views/moderation/comments/index.html.erb +++ b/app/views/moderation/comments/index.html.erb @@ -2,14 +2,10 @@ <%= render 'shared/filter_subnav', i18n_namespace: "moderation.comments.index" %> -
-

<%= page_entries_info @comments %>

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

<%= page_entries_info @comments %>

+
+ <%= t("moderation.comments.index.order") %> + <%= render 'shared/order_selector', i18n_namespace: "moderation.comments.index" %>
<%= form_tag moderate_moderation_comments_path(request.query_parameters), method: :put do %> diff --git a/app/views/moderation/debates/index.html.erb b/app/views/moderation/debates/index.html.erb index 4fecee50b..86583fc3d 100644 --- a/app/views/moderation/debates/index.html.erb +++ b/app/views/moderation/debates/index.html.erb @@ -2,14 +2,10 @@ <%= render 'shared/filter_subnav', i18n_namespace: "moderation.debates.index" %> -
-

<%= page_entries_info @debates %>

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

<%= page_entries_info @debates %>

+
+ <%= t("moderation.debates.index.order") %> + <%= render 'shared/order_selector', i18n_namespace: "moderation.debates.index" %>
<%= form_tag moderate_moderation_debates_path(request.query_parameters), method: :put do %> diff --git a/app/views/moderation/proposals/index.html.erb b/app/views/moderation/proposals/index.html.erb index 91149e0b0..6c5c671a7 100644 --- a/app/views/moderation/proposals/index.html.erb +++ b/app/views/moderation/proposals/index.html.erb @@ -2,14 +2,10 @@ <%= render 'shared/filter_subnav', i18n_namespace: "moderation.proposals.index" %> -
-

<%= page_entries_info @proposals %>

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

<%= page_entries_info @proposals %>

+
+ <%= t("moderation.proposals.index.order") %> + <%= render 'shared/order_selector', i18n_namespace: "moderation.proposals.index" %>
<%= form_tag moderate_moderation_proposals_path(request.query_parameters), method: :put do %> From 4a6313fed7cb78ac0024fba2a12824bb018633b8 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Tue, 19 Jun 2018 11:32:20 -0400 Subject: [PATCH 006/341] Add missing `thead` & `tbody` tags on moderation index views --- app/views/moderation/comments/index.html.erb | 88 +++++++++---------- app/views/moderation/debates/index.html.erb | 81 +++++++++-------- .../proposal_notifications/index.html.erb | 78 ++++++++-------- app/views/moderation/proposals/index.html.erb | 84 +++++++++--------- 4 files changed, 164 insertions(+), 167 deletions(-) diff --git a/app/views/moderation/comments/index.html.erb b/app/views/moderation/comments/index.html.erb index ae919a71c..f9c5ee341 100644 --- a/app/views/moderation/comments/index.html.erb +++ b/app/views/moderation/comments/index.html.erb @@ -9,63 +9,61 @@
<%= form_tag moderate_moderation_comments_path(request.query_parameters), method: :put do %> -

+

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

- - - - - - - <% @comments.each do |comment| %> - - - +
- <%= t("moderation.comments.index.headers.comment") %> - - <%= t("moderation.comments.index.headers.moderate") %> -
- <%= comment.commentable_type.constantize.model_name.human %> - - <%= link_to comment.commentable.title, commentable_path(comment) %> -
- <%= l comment.updated_at.to_date %> -  •  - <%= comment.flags_count %> -  •  - <%= comment.author.username %> -
-

- <%= comment.body %> -

-
- <%= check_box_tag "comment_ids[]", comment.id, nil, id: "#{dom_id(comment)}_check" %> -
+ + + + - <% end %> + + + + <% @comments.each do |comment| %> + + + + + <% end %> +
<%= t("moderation.comments.index.headers.comment") %><%= t("moderation.comments.index.headers.moderate") %>
+ <%= comment.commentable_type.constantize.model_name.human %> - + <%= link_to comment.commentable.title, commentable_path(comment), target: "_blank" %> +
+ <%= l comment.updated_at.to_date %> +  •  + <%= comment.flags_count %> +  •  + <%= comment.author.username %> +
+
+ <%= comment.body %> +
+
+ <%= check_box_tag "comment_ids[]", comment.id, nil, id: "#{dom_id(comment)}_check" %> +
<%= submit_tag t('moderation.comments.index.block_authors'), - name: "block_authors", - class: "button hollow alert", - data: {confirm: t('moderation.comments.index.confirm')} - %> + name: "block_authors", + class: "button hollow alert", + data: { confirm: t('moderation.comments.index.confirm') } %>
<%= submit_tag t('moderation.comments.index.hide_comments'), - name: "hide_comments", - class: "button hollow alert", - data: {confirm: t('moderation.comments.index.confirm')} - %> + name: "hide_comments", + class: "button hollow alert", + data: { confirm: t('moderation.comments.index.confirm') } %> + <%= submit_tag t('moderation.comments.index.ignore_flags'), - name: "ignore_flags", - class: "button hollow", - data: {confirm: t('moderation.comments.index.confirm')} - %> + name: "ignore_flags", + class: "button hollow", + data: { confirm: t('moderation.comments.index.confirm') } %>
<%= paginate @comments %> diff --git a/app/views/moderation/debates/index.html.erb b/app/views/moderation/debates/index.html.erb index 86583fc3d..c0fae2919 100644 --- a/app/views/moderation/debates/index.html.erb +++ b/app/views/moderation/debates/index.html.erb @@ -11,59 +11,58 @@ <%= form_tag moderate_moderation_debates_path(request.query_parameters), method: :put do %>

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

- - - - - <% @debates.each do |debate| %> - - - + + + + - <% end %> + + + + <% @debates.each do |debate| %> + + + + + <% end %> +
- <%= t("moderation.debates.index.headers.debate") %> - - <%= t("moderation.debates.index.headers.moderate") %> -
- <%= link_to debate.title, debate, target: "_blank" %> -
- <%= l debate.updated_at.to_date %> -  •  - <%= debate.flags_count %> -  •  - <%= debate.author.username %> -
-
- <%= debate.description %> -
-
- <%= check_box_tag "debate_ids[]", debate.id, nil, id: "#{dom_id(debate)}_check" %> -
<%= t("moderation.debates.index.headers.debate") %><%= t("moderation.debates.index.headers.moderate") %>
+ <%= link_to debate.title, debate, target: "_blank" %> +
+ <%= l debate.updated_at.to_date %> +  •  + <%= debate.flags_count %> +  •  + <%= debate.author.username %> +
+
+ <%= debate.description %> +
+
+ <%= check_box_tag "debate_ids[]", debate.id, nil, id: "#{dom_id(debate)}_check" %> +
<%= submit_tag t('moderation.debates.index.block_authors'), - name: "block_authors", - class: "button alert", - data: {confirm: t('moderation.debates.index.confirm')} - %> + name: "block_authors", + class: "button hollow alert", + data: { confirm: t('moderation.debates.index.confirm') } %>
<%= submit_tag t('moderation.debates.index.hide_debates'), - name: "hide_debates", - class: "button alert", - data: {confirm: t('moderation.debates.index.confirm')} - %> + name: "hide_debates", + class: "button hollow alert", + data: { confirm: t('moderation.debates.index.confirm') } %> + <%= submit_tag t('moderation.debates.index.ignore_flags'), - name: "ignore_flags", - class: "button success", - data: {confirm: t('moderation.debates.index.confirm')} - %> + name: "ignore_flags", + class: "button hollow", + data: { confirm: t('moderation.debates.index.confirm') } %>
<%= paginate @debates %> diff --git a/app/views/moderation/proposal_notifications/index.html.erb b/app/views/moderation/proposal_notifications/index.html.erb index bc8615c35..e32f3d1da 100644 --- a/app/views/moderation/proposal_notifications/index.html.erb +++ b/app/views/moderation/proposal_notifications/index.html.erb @@ -9,57 +9,59 @@
<%= form_tag moderate_moderation_proposal_notifications_path(request.query_parameters), method: :put do %> -

+

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

- - - - - <% @proposal_notifications.each do |proposal_notification| %> - - - + + + + - <% end %> + + + + <% @proposal_notifications.each do |proposal_notification| %> + + + + + <% end %> +
- <%= t("moderation.proposal_notifications.index.headers.proposal_notification") %> - - <%= t("moderation.proposal_notifications.index.headers.moderate") %> -
- <%= link_to proposal_notification.title, proposal_notification, target: "_blank" %> -
- <%= l proposal_notification.updated_at.to_date %> -
-
- <%= proposal_notification.body %> -
-
- <%= check_box_tag "proposal_notification_ids[]", proposal_notification.id, nil, id: "#{dom_id(proposal_notification)}_check" %> -
<%= t("moderation.proposal_notifications.index.headers.proposal_notification") %><%= t("moderation.proposal_notifications.index.headers.moderate") %>
+ <%= link_to proposal_notification.title, proposal_notification, target: "_blank" %> +
+ <%= l proposal_notification.updated_at.to_date %> +
+
+ <%= proposal_notification.body %> +
+
+ <%= check_box_tag "proposal_notification_ids[]", + proposal_notification.id, + nil, + id: "#{dom_id(proposal_notification)}_check" %> +
<%= submit_tag t('moderation.proposal_notifications.index.block_authors'), - name: "block_authors", - class: "button hollow alert", - data: {confirm: t('moderation.proposal_notifications.index.confirm')} - %> + name: "block_authors", + class: "button hollow alert", + data: { confirm: t('moderation.proposal_notifications.index.confirm') } %>
<%= submit_tag t('moderation.proposal_notifications.index.hide_proposal_notifications'), - name: "hide_proposal_notifications", - class: "button hollow alert", - data: {confirm: t('moderation.proposal_notifications.index.confirm')} - %> + name: "hide_proposal_notifications", + class: "button hollow alert", + data: { confirm: t('moderation.proposal_notifications.index.confirm') } %> + <%= submit_tag t('moderation.proposal_notifications.index.ignore_flags'), - name: "ignore_flags", - class: "button hollow", - data: {confirm: t('moderation.proposal_notifications.index.confirm')} - %> + name: "ignore_flags", + class: "button hollow", + data: { confirm: t('moderation.proposal_notifications.index.confirm') } %>
<%= paginate @proposal_notifications %> diff --git a/app/views/moderation/proposals/index.html.erb b/app/views/moderation/proposals/index.html.erb index 6c5c671a7..8173f07ca 100644 --- a/app/views/moderation/proposals/index.html.erb +++ b/app/views/moderation/proposals/index.html.erb @@ -9,64 +9,62 @@
<%= form_tag moderate_moderation_proposals_path(request.query_parameters), method: :put do %> -

+

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

- - - - - <% @proposals.each do |proposal| %> - - - + + + + - <% end %> + + + + <% @proposals.each do |proposal| %> + + + + + <% end %> +
- <%= t("moderation.proposals.index.headers.proposal") %> - - <%= t("moderation.proposals.index.headers.moderate") %> -
- <%= link_to proposal.title, proposal, target: "_blank" %> -
- <%= l proposal.updated_at.to_date %> -  •  - <%= proposal.flags_count %> -  •  - <%= proposal.author.username %> -
-
- <%= proposal.description %> -
-
- <%= check_box_tag "proposal_ids[]", proposal.id, nil, id: "#{dom_id(proposal)}_check" %> -
<%= t("moderation.proposals.index.headers.proposal") %><%= t("moderation.proposals.index.headers.moderate") %>
+ <%= link_to proposal.title, proposal, target: "_blank" %> +
+ <%= l proposal.updated_at.to_date %> +  •  + <%= proposal.flags_count %> +  •  + <%= proposal.author.username %> +
+
+ <%= proposal.description %> +
+
+ <%= check_box_tag "proposal_ids[]", proposal.id, nil, id: "#{dom_id(proposal)}_check" %> +
<%= submit_tag t('moderation.proposals.index.block_authors'), - name: "block_authors", - class: "button hollow alert", - data: {confirm: t('moderation.proposals.index.confirm')} - %> + name: "block_authors", + class: "button hollow alert", + data: { confirm: t('moderation.proposals.index.confirm') } %>
<%= submit_tag t('moderation.proposals.index.hide_proposals'), - name: "hide_proposals", - class: "button hollow alert", - data: {confirm: t('moderation.proposals.index.confirm')} - %> + name: "hide_proposals", + class: "button hollow alert", + data: { confirm: t('moderation.proposals.index.confirm') } %> + <%= submit_tag t('moderation.proposals.index.ignore_flags'), - name: "ignore_flags", - class: "button hollow", - data: {confirm: t('moderation.proposals.index.confirm')} - %> + name: "ignore_flags", + class: "button hollow", + data: { confirm: t('moderation.proposals.index.confirm') } %>
<%= paginate @proposals %> <% end %> - From 90bb06e68461d413f8877003d80d0abf4ddf7149 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 4 Mar 2018 22:29:40 +0100 Subject: [PATCH 007/341] Fix display of unfeasibility explanation We were missing a check to make sure valuation had finished before displaying the unfeasibility explanation --- spec/features/budgets/investments_spec.rb | 18 +++++++++++ spec/models/budget/investment_spec.rb | 38 +++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 51445bccc..4347fb212 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -991,6 +991,24 @@ feature 'Budget Investments' do expect(page).not_to have_content("Local government is not competent in this matter") end + scenario "Show (unfeasible budget investment with valuation not finished)" do + user = create(:user) + login_as(user) + + investment = create(:budget_investment, + :unfeasible, + valuation_finished: false, + budget: budget, + group: group, + heading: heading, + unfeasibility_explanation: 'Local government is not competent in this matter') + + visit budget_investment_path(budget_id: budget.id, id: investment.id) + + expect(page).not_to have_content("Unfeasibility explanation") + expect(page).not_to have_content(investment.unfeasibility_explanation) + end + scenario "Show milestones", :js do user = create(:user) investment = create(:budget_investment) diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index a4e1d246d..e9081cf34 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -308,6 +308,44 @@ describe Budget::Investment do end end + describe "#by_budget" do + + it "returns true for unfeasible investments with unfeasibility explanation and valuation finished" do + Budget::Phase::PUBLISHED_PRICES_PHASES.each do |phase| + budget.update(phase: phase) + + expect(investment.should_show_unfeasibility_explanation?).to eq(true) + end + end + + it "returns false in valuation has not finished" do + investment.update(valuation_finished: false) + Budget::Phase::PUBLISHED_PRICES_PHASES.each do |phase| + budget.update(phase: phase) + + expect(investment.should_show_unfeasibility_explanation?).to eq(false) + end + end + + it "returns false if not unfeasible" do + investment.update(feasibility: "undecided") + Budget::Phase::PUBLISHED_PRICES_PHASES.each do |phase| + budget.update(phase: phase) + + expect(investment.should_show_unfeasibility_explanation?).to eq(false) + end + end + + it "returns false if unfeasibility explanation blank" do + investment.update(unfeasibility_explanation: "") + Budget::Phase::PUBLISHED_PRICES_PHASES.each do |phase| + budget.update(phase: phase) + + expect(investment.should_show_unfeasibility_explanation?).to eq(false) + end + end + end + describe "#by_admin" do it "returns investments assigned to specific administrator" do investment1 = create(:budget_investment, administrator_id: 33) From b3978908b2e5cd791c9e159a559de7a7f6d3cd0e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 5 Mar 2018 01:05:36 +0100 Subject: [PATCH 008/341] Use strings instead of method calls in expectations --- spec/features/budgets/investments_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 4347fb212..dbc82ba31 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -1006,7 +1006,7 @@ feature 'Budget Investments' do visit budget_investment_path(budget_id: budget.id, id: investment.id) expect(page).not_to have_content("Unfeasibility explanation") - expect(page).not_to have_content(investment.unfeasibility_explanation) + expect(page).not_to have_content("Local government is not competent in this matter") end scenario "Show milestones", :js do From 81d8b9b9ed757b6199a5deb7d0d22f2bc8e912d6 Mon Sep 17 00:00:00 2001 From: iagirre Date: Thu, 16 Nov 2017 16:36:09 +0100 Subject: [PATCH 009/341] 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 010/341] 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 013/341] 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 014/341] 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 015/341] 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 016/341] 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 017/341] 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 018/341] 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 019/341] 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 020/341] 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 021/341] 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 022/341] 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 023/341] 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 024/341] 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 025/341] 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 026/341] 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 8b78dd88a008be28384f03000e5a53e46a40fa3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Mart=C3=ADn?= Date: Wed, 25 Jul 2018 01:43:13 +0200 Subject: [PATCH 027/341] Fix typo in proposal notifications spec. --- spec/features/moderation/proposal_notifications_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/moderation/proposal_notifications_spec.rb b/spec/features/moderation/proposal_notifications_spec.rb index 4af3a815d..396173190 100644 --- a/spec/features/moderation/proposal_notifications_spec.rb +++ b/spec/features/moderation/proposal_notifications_spec.rb @@ -16,7 +16,7 @@ feature 'Moderate proposal notifications' do accept_confirm { click_link 'Hide' } end - expect(page).to have_css("#proposal_notification_#{proposal.id}.faded") + expect(page).to have_css("#proposal_notification_#{proposal_notification.id}.faded") logout login_as(citizen) From e9d73eb687e35c7a610094a24ec2d7993d93eeb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Tue, 10 Apr 2018 17:53:57 +0200 Subject: [PATCH 028/341] Fix `max_per_heading` filter in Admin budget investments list Also changed the name of the param to `min_total_supports`, which is more descriptive on what it actually does. Backport of 75f20d5 and 07f0806 from AyuntamientoMadrid/consul fork --- .../admin_budget_investments_helper.rb | 2 +- app/models/budget/investment.rb | 15 +---- .../budget_investments/_investments.html.erb | 4 +- .../budget_investments/_search_form.html.erb | 2 +- config/locales/en/admin.yml | 2 +- config/locales/es/admin.yml | 2 +- .../features/admin/budget_investments_spec.rb | 61 +++++++------------ 7 files changed, 29 insertions(+), 59 deletions(-) diff --git a/app/helpers/admin_budget_investments_helper.rb b/app/helpers/admin_budget_investments_helper.rb index 742ff5bac..492225e35 100644 --- a/app/helpers/admin_budget_investments_helper.rb +++ b/app/helpers/admin_budget_investments_helper.rb @@ -1,7 +1,7 @@ module AdminBudgetInvestmentsHelper def advanced_menu_visibility - (params[:advanced_filters].empty? && params["max_per_heading"].blank?) ? 'hide' : '' + (params[:advanced_filters].empty? && params["min_total_supports"].blank?) ? 'hide' : '' end def init_advanced_menu diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index ee3292fcd..1e2d3887c 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -109,7 +109,8 @@ class Budget budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) results = Investment.by_budget(budget) - results = limit_results(budget, params, results) if params[:max_per_heading].present? + results = results.where("cached_votes_up + physical_votes >= ?", + params[:min_total_supports]) if params[:min_total_supports].present? results = results.where(group_id: params[:group_id]) if params[:group_id].present? results = results.by_tag(params[:tag_name]) if params[:tag_name].present? results = results.by_heading(params[:heading_id]) if params[:heading_id].present? @@ -132,18 +133,6 @@ class Budget results.where("budget_investments.id IN (?)", ids) end - def self.limit_results(budget, params, results) - max_per_heading = params[:max_per_heading].to_i - return results if max_per_heading <= 0 - - ids = [] - budget.headings.pluck(:id).each do |hid| - ids += Investment.where(heading_id: hid).order(confidence_score: :desc).limit(max_per_heading).pluck(:id) - end - - results.where("budget_investments.id IN (?)", ids) - end - def self.search_by_title_or_id(title_or_id, results) if title_or_id =~ /^[0-9]+$/ results.where(id: title_or_id) diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb index 17b0315b1..db10e2210 100644 --- a/app/views/admin/budget_investments/_investments.html.erb +++ b/app/views/admin/budget_investments/_investments.html.erb @@ -112,7 +112,7 @@ investment, filter: params[:filter], sort_by: params[:sort_by], - max_per_heading: params[:max_per_heading], + min_total_supports: params[:min_total_supports], advanced_filters: params[:advanced_filters], page: params[:page]), method: :patch, @@ -125,7 +125,7 @@ investment, filter: params[:filter], sort_by: params[:sort_by], - max_per_heading: params[:max_per_heading], + min_total_supports: params[:min_total_supports], advanced_filters: params[:advanced_filters], page: params[:page]), method: :patch, diff --git a/app/views/admin/budget_investments/_search_form.html.erb b/app/views/admin/budget_investments/_search_form.html.erb index 0f3090c60..dc3269443 100644 --- a/app/views/admin/budget_investments/_search_form.html.erb +++ b/app/views/admin/budget_investments/_search_form.html.erb @@ -18,7 +18,7 @@ <% end %>
    - <%= text_field_tag :max_per_heading, params["max_per_heading"], placeholder: t("admin.budget_investments.index.filters.max_per_heading") %> + <%= text_field_tag :min_total_supports, params["min_total_supports"], placeholder: t("admin.budget_investments.index.filters.min_total_supports") %>
    diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 48ee46db6..aab916b53 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -167,7 +167,7 @@ en: selected: Selected undecided: Undecided unfeasible: Unfeasible - max_per_heading: Max. supports per heading + min_total_supports: Minimum supports winners: Winners one_filter_html: "Current applied filters: %{filter}" two_filters_html: "Current applied filters: %{filter}, %{advanced_filters}" diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 8929f9e3b..d01c38e79 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -167,7 +167,7 @@ es: selected: Seleccionados undecided: Sin decidir unfeasible: Inviables - max_per_heading: Corte por partida + min_total_supports: Apoyos mínimos winners: Ganadores one_filter_html: "Filtros en uso: %{filter}" two_filters_html: "Filtros en uso: %{filter}, %{advanced_filters}" diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index de34f5298..874615475 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -371,59 +371,40 @@ feature 'Admin budget investments' do expect(page).to have_content 'The budget has to stay on phase "Balloting projects", "Reviewing Ballots" or "Finished budget" in order to calculate winners projects' end - scenario "Limiting by max number of investments per heading", :js do + scenario "Filtering by minimum number of votes", :js do group_1 = create(:budget_group, budget: budget) group_2 = create(:budget_group, budget: budget) parks = create(:budget_heading, group: group_1) roads = create(:budget_heading, group: group_2) streets = create(:budget_heading, group: group_2) - [2, 4, 90, 100, 200, 300].each do |n| - create(:budget_investment, heading: parks, cached_votes_up: n, title: "Park with #{n} supports") - end - - [21, 31, 51, 81, 91, 101].each do |n| - create(:budget_investment, heading: roads, cached_votes_up: n, title: "Road with #{n} supports") - end - - [3, 10, 30, 33, 44, 55].each do |n| - create(:budget_investment, heading: streets, cached_votes_up: n, title: "Street with #{n} supports") - end + create(:budget_investment, heading: parks, cached_votes_up: 40, title: "Park with 40 supports") + create(:budget_investment, heading: parks, cached_votes_up: 99, title: "Park with 99 supports") + create(:budget_investment, heading: roads, cached_votes_up: 100, title: "Road with 100 supports") + create(:budget_investment, heading: roads, cached_votes_up: 199, title: "Road with 199 supports") + create(:budget_investment, heading: streets, cached_votes_up: 200, title: "Street with 200 supports") + create(:budget_investment, heading: streets, cached_votes_up: 300, title: "Street with 300 supports") visit admin_budget_budget_investments_path(budget) - [2, 4, 90, 100, 200, 300].each do |n| - expect(page).to have_link("Park with #{n} supports") - end - - [21, 31, 51, 81, 91, 101].each do |n| - expect(page).to have_link("Road with #{n} supports") - end - - [3, 10, 30, 33, 44, 55].each do |n| - expect(page).to have_link("Street with #{n} supports") - end + expect(page).to have_link("Park with 40 supports") + expect(page).to have_link("Park with 99 supports") + expect(page).to have_link("Road with 100 supports") + expect(page).to have_link("Road with 199 supports") + expect(page).to have_link("Street with 200 supports") + expect(page).to have_link("Street with 300 supports") click_link 'Advanced filters' - fill_in "max_per_heading", with: 5 + fill_in "min_total_supports", with: 180 click_button 'Filter' - expect(page).to have_content('There are 15 investments') - expect(page).not_to have_link("Park with 2 supports") - expect(page).not_to have_link("Road with 21 supports") - expect(page).not_to have_link("Street with 3 supports") - - [4, 90, 100, 200, 300].each do |n| - expect(page).to have_link("Park with #{n} supports") - end - - [31, 51, 81, 91, 101].each do |n| - expect(page).to have_link("Road with #{n} supports") - end - - [10, 30, 33, 44, 55].each do |n| - expect(page).to have_link("Street with #{n} supports") - end + expect(page).to have_content('There are 3 investments') + expect(page).to have_link("Road with 199 supports") + expect(page).to have_link("Street with 200 supports") + expect(page).to have_link("Street with 300 supports") + expect(page).not_to have_link("Park with 40 supports") + expect(page).not_to have_link("Park with 99 supports") + expect(page).not_to have_link("Road with 100 supports") end scenario "Combination of checkbox with text search", :js do From 3fd97b0a9b313dbe3c668008f89e30192d0ab3d1 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Thu, 12 Apr 2018 11:21:15 +0200 Subject: [PATCH 029/341] Rename Newsletter & Notification to User Messages We're increasing the features around messaging users, menu name has to be generic enough. --- app/views/admin/_menu.html.erb | 16 ++++++++-------- config/locales/en/admin.yml | 2 +- config/locales/es/admin.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index e5af32cc4..e1d6cc0de 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -79,21 +79,21 @@
  • <% end %> - <% newsletters_notifications_sections = %w(newsletters emails_download admin_notifications) %> - <% newsletters_menu_active = newsletters_notifications_sections.include?(controller_name) %> -
  • > + <% messages_sections = %w(newsletters emails_download admin_notifications) %> + <% messages_menu_active = messages_sections.include?(controller_name) %> +
  • > - <%= t("admin.menu.newsletters_and_notifications") %> + <%= t("admin.menu.messaging_users") %> - From a37b64dfb6ac74bd506886a55cd704017334ed26 Mon Sep 17 00:00:00 2001 From: Ziyan Junaideen Date: Thu, 26 Jul 2018 15:32:43 +0530 Subject: [PATCH 063/341] i18n desc for content block known keys + use in select in form --- .../admin/site_customization/content_blocks/_form.html.erb | 2 +- config/locales/en/admin.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb index ca89b8781..28a92fb12 100644 --- a/app/views/admin/site_customization/content_blocks/_form.html.erb +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -17,7 +17,7 @@
    <%= f.label :name %> - <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS, label: false %> + <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS.map { |key| [t("admin.site_customization.content_blocks.content_block.names.#{key}", key] }, label: false %>
    <%= f.label :locale %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 259ea7c44..12652f76c 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1276,6 +1276,11 @@ en: content_block: body: Body name: Name + names: + top_links: Top Links + footer: Footer + subnavigation_left: Main Navigation Left + subnavigation_right: Main Navigation Right images: index: title: Custom images From a6bbf32b8e979f7e01032fb6eeffdbd179701a61 Mon Sep 17 00:00:00 2001 From: Ziyan Junaideen Date: Thu, 26 Jul 2018 15:37:22 +0530 Subject: [PATCH 064/341] Content blocks - new keys --- app/models/site_customization/content_block.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site_customization/content_block.rb b/app/models/site_customization/content_block.rb index 01d2206b6..81d624ac3 100644 --- a/app/models/site_customization/content_block.rb +++ b/app/models/site_customization/content_block.rb @@ -1,5 +1,5 @@ class SiteCustomization::ContentBlock < ActiveRecord::Base - VALID_BLOCKS = %w(top_links footer main_navigation_left main_navigation_right) + VALID_BLOCKS = %w(top_links footer subnavigation_left subnavigation_right) validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } validates :name, presence: true, uniqueness: { scope: :locale }, inclusion: { in: VALID_BLOCKS } From 9bad639bb5174849888f6f64aa4072bdf3cff407 Mon Sep 17 00:00:00 2001 From: Ziyan Junaideen Date: Thu, 26 Jul 2018 15:37:38 +0530 Subject: [PATCH 065/341] i18n usage - typo + sub navigation using new keys --- .../admin/site_customization/content_blocks/_form.html.erb | 2 +- app/views/shared/_subnavigation.html.erb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb index 28a92fb12..2a0e990b2 100644 --- a/app/views/admin/site_customization/content_blocks/_form.html.erb +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -17,7 +17,7 @@
    <%= f.label :name %> - <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS.map { |key| [t("admin.site_customization.content_blocks.content_block.names.#{key}", key] }, label: false %> + <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS.map { |key| [t("admin.site_customization.content_blocks.content_block.names.#{key}"), key] }, label: false %>
    <%= f.label :locale %> diff --git a/app/views/shared/_subnavigation.html.erb b/app/views/shared/_subnavigation.html.erb index 3336dad0a..f68367077 100644 --- a/app/views/shared/_subnavigation.html.erb +++ b/app/views/shared/_subnavigation.html.erb @@ -1,6 +1,6 @@
      - <%= raw content_block("main_navigation_left", I18n.locale) %> + <%= raw content_block("subnavigation_left", I18n.locale) %> <% if feature?(:debates) %>
    • @@ -62,6 +62,6 @@ title: t("shared.go_to_page") + t("layouts.header.help") %>
    • - <%= raw content_block("main_navigation_right", I18n.locale) %> + <%= raw content_block("subnavigation_right", I18n.locale) %>
    From ffe7465b86913b8731e63335dd13e5bc2671d49d Mon Sep 17 00:00:00 2001 From: Ziyan Junaideen Date: Thu, 26 Jul 2018 21:43:39 +0530 Subject: [PATCH 066/341] Spec adjustments --- .../admin/site_customization/content_blocks_spec.rb | 4 ++-- spec/features/site_customization/content_blocks_spec.rb | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/admin/site_customization/content_blocks_spec.rb b/spec/features/admin/site_customization/content_blocks_spec.rb index eb6098ed4..5f8cd6681 100644 --- a/spec/features/admin/site_customization/content_blocks_spec.rb +++ b/spec/features/admin/site_customization/content_blocks_spec.rb @@ -27,7 +27,7 @@ feature "Admin custom content blocks" do click_link "Create new content block" - select "footer", from: "site_customization_content_block_name" + select I18n.t("admin.site_customization.content_blocks.content_block.names.footer"), from: "site_customization_content_block_name" select "es", from: "site_customization_content_block_locale" fill_in "site_customization_content_block_body", with: "Some custom content" @@ -50,7 +50,7 @@ feature "Admin custom content blocks" do click_link "Create new content block" - select "top_links", from: "site_customization_content_block_name" + select I18n.t("admin.site_customization.content_blocks.content_block.names.top_links"), from: "site_customization_content_block_name" select "en", from: "site_customization_content_block_locale" fill_in "site_customization_content_block_body", with: "Some custom content" diff --git a/spec/features/site_customization/content_blocks_spec.rb b/spec/features/site_customization/content_blocks_spec.rb index e9db53a89..8fc34c9c2 100644 --- a/spec/features/site_customization/content_blocks_spec.rb +++ b/spec/features/site_customization/content_blocks_spec.rb @@ -32,8 +32,8 @@ feature "Custom content blocks" do end scenario "main navigation left" do - create(:site_customization_content_block, name: "main_navigation_left", locale: "en", body: "content for left links") - create(:site_customization_content_block, name: "main_navigation_left", locale: "es", body: "contenido para left links") + create(:site_customization_content_block, name: "subnavigation_left", locale: "en", body: "content for left links") + create(:site_customization_content_block, name: "subnavigation_left", locale: "es", body: "contenido para left links") visit "/?locale=en" @@ -47,8 +47,8 @@ feature "Custom content blocks" do end scenario "main navigation right" do - create(:site_customization_content_block, name: "main_navigation_right", locale: "en", body: "content for right links") - create(:site_customization_content_block, name: "main_navigation_right", locale: "es", body: "contenido para right links") + create(:site_customization_content_block, name: "subnavigation_right", locale: "en", body: "content for right links") + create(:site_customization_content_block, name: "subnavigation_right", locale: "es", body: "contenido para right links") visit "/?locale=en" 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 067/341] 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 068/341] 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 069/341] 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 070/341] 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 071/341] 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 072/341] 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 073/341] 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 074/341] 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 075/341] 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 076/341] 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 077/341] 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 078/341] 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 079/341] 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 080/341] 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 081/341] 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 082/341] 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 083/341] 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 084/341] 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 085/341] 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 086/341] 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 087/341] 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 088/341] 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 089/341] 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 090/341] 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 091/341] 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 092/341] 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 093/341] 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 094/341] 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 095/341] 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 096/341] 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 097/341] 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 098/341] 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 099/341] 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 100/341] 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 101/341] 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 102/341] 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 f78d81bc81a4e807b4cbcb53799dab4885e6bcb0 Mon Sep 17 00:00:00 2001 From: Ziyan Junaideen Date: Fri, 27 Jul 2018 20:13:53 +0530 Subject: [PATCH 103/341] ES admin i18n --- config/locales/es/admin.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 00cd907a3..5fbd2b016 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1277,6 +1277,11 @@ es: content_block: body: Contenido name: Nombre + names: + top_links: Enlaces superiores + footer: Pie de página + subnavigation_left: Navegación principal izquierda + subnavigation_right: Navegación principal derecha images: index: title: Personalizar imágenes From 157cd001d5bf2e014a7e87e1791b081f2f788db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Mart=C3=ADn?= Date: Sat, 28 Jul 2018 21:28:22 +0200 Subject: [PATCH 104/341] Add spec to expose a bug finding manager logged in I've moved the method to the User model in order to make it easier to test. I'm not sure where it belongs, though. There was already a failing spec in `spec/features/management_spec.rb`, but it passed if run standalone because it only failed if previous tests had already created nine users or more. --- app/controllers/management/base_controller.rb | 2 +- app/models/user.rb | 4 ++++ spec/models/user_spec.rb | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/controllers/management/base_controller.rb b/app/controllers/management/base_controller.rb index 1bae36a76..ba8ece9f2 100644 --- a/app/controllers/management/base_controller.rb +++ b/app/controllers/management/base_controller.rb @@ -56,7 +56,7 @@ class Management::BaseController < ActionController::Base def manager_logged_in if current_manager - @manager_logged_in = User.find_by(id: session[:manager]["login"].last(1)) + @manager_logged_in = User.find_by_manager_login(session[:manager]["login"]) end end diff --git a/app/models/user.rb b/app/models/user.rb index 4b999207d..604132857 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -329,6 +329,10 @@ class User < ActiveRecord::Base where(conditions.to_hash).where(["username = ?", login]).first end + def self.find_by_manager_login(manager_login) + find_by(id: manager_login.last(1)) + end + def interests followables = follows.map(&:followable) followables.compact.map { |followable| followable.tags.map(&:name) }.flatten.compact.uniq diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index c201fc03c..1d860e121 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -690,4 +690,17 @@ describe User do end + describe ".find_by_manager_login" do + it "works with a low ID" do + user = create(:user) + expect(User.find_by_manager_login("admin_user_#{user.id}")).to eq user + end + + it "works with a high ID" do + 10.times { create(:user) } + user = User.last + expect(User.find_by_manager_login("admin_user_#{user.id}")).to eq user + end + end + end From 3b820571789bf86b2c769a006933ac525cb6909d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Mart=C3=ADn?= Date: Sat, 28 Jul 2018 21:43:51 +0200 Subject: [PATCH 105/341] Fix admin menu not showing for some admins There was a bug when finding the manager login, since we were only using the last digit of their user ID. --- app/models/user.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index 604132857..3a274f056 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -330,7 +330,7 @@ class User < ActiveRecord::Base end def self.find_by_manager_login(manager_login) - find_by(id: manager_login.last(1)) + find_by(id: manager_login.split("_").last) end def interests From 2543cf5d6cc9a1858df80c68b1dd2dfccad3430f Mon Sep 17 00:00:00 2001 From: decabeza Date: Mon, 30 Jul 2018 17:45:19 +0200 Subject: [PATCH 106/341] 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 107/341] 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 108/341] 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 @@