From e5c73d8f02f21d4af554365d7c2919daa82105cf Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 18 Jan 2018 20:50:16 -0400 Subject: [PATCH 1/9] Add advanced filters for Admin::Budget::Investment --- .../admin/budget_investments_controller.rb | 1 + app/models/budget/investment.rb | 35 +++++++++++++++---- .../_advanced_filters.html.erb | 27 ++++++++++++++ .../admin/budget_investments/index.html.erb | 24 +++++++------ .../admin/budget_investments/index.js.erb | 1 + config/locales/en/admin.yml | 5 +++ config/locales/es/admin.yml | 7 +++- 7 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 app/views/admin/budget_investments/_advanced_filters.html.erb create mode 100644 app/views/admin/budget_investments/index.js.erb diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index dbaa91f99..7a57c8814 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -15,6 +15,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController def index respond_to do |format| format.html + format.js { render layout: false } format.csv do send_data Budget::Investment.to_csv(@investments, headers: true), filename: 'budget_investments.csv' diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index da99db004..21cdab879 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -1,6 +1,7 @@ +require 'csv' + class Budget class Investment < ActiveRecord::Base - require 'csv' include Rails.application.routes.url_helpers include Measurable include Sanitizable @@ -53,7 +54,7 @@ class Budget scope :valuation_open, -> { where(valuation_finished: false) } scope :without_admin, -> { valuation_open.where(administrator_id: nil) } scope :managed, -> { valuation_open.where(valuator_assignments_count: 0).where("administrator_id IS NOT ?", nil) } - scope :valuating, -> { valuation_open.where("valuator_assignments_count > 0 AND valuation_finished = ?", false) } + scope :valuating, -> { valuation_open.where("valuator_assignments_count > 0") } scope :valuation_finished, -> { where(valuation_finished: true) } scope :valuation_finished_feasible, -> { where(valuation_finished: true, feasibility: "feasible") } scope :feasible, -> { where(feasibility: "feasible") } @@ -86,20 +87,42 @@ class Budget end def self.filter_params(params) - params.select{|x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include? x.to_s } + params.select{ |x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include?(x.to_s) } end def self.scoped_filter(params, current_filter) - results = Investment.where(budget_id: params[:budget_id]) + budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) + results = Investment.where(budget_id: budget.id) + + results = limit_results(budget, params, results) if params[:max_per_heading].present? results = results.where(group_id: params[:group_id]) if params[:group_id].present? - results = results.by_heading(params[:heading_id]) if params[:heading_id].present? - results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present? results = results.by_tag(params[:tag_name]) if params[:tag_name].present? + results = results.by_heading(params[:heading_id]) if params[:heading_id].present? results = results.by_valuator(params[:valuator_id]) if params[:valuator_id].present? + results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present? + + # Advanced filters + results = results.valuation_finished_feasible if params[:second_filter] == 'feasible' + results = results.where(selected: true) if params[:second_filter] == 'selected' + results = results.undecided if params[:second_filter] == 'undecided' + results = results.unfeasible if params[:second_filter] == 'unfeasible' + results = results.send(current_filter) if current_filter.present? results.includes(:heading, :group, :budget, administrator: :user, valuators: :user) 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 searchable_values { title => 'A', author.username => 'B', diff --git a/app/views/admin/budget_investments/_advanced_filters.html.erb b/app/views/admin/budget_investments/_advanced_filters.html.erb new file mode 100644 index 000000000..e9b68efa8 --- /dev/null +++ b/app/views/admin/budget_investments/_advanced_filters.html.erb @@ -0,0 +1,27 @@ +
+ <%= form_tag(admin_budget_budget_investments_path(budget: @budget, + filter: params[:filter], + second_filter: params[:second_filter], + max_per_heading: params[:max_per_heading], + page: 1), method: :get, remote: true, enforce_utf8: false) do %> + + <%= check_box_tag :second_filter, "feasible" %> + <%= t("#{i18n_namespace}.filters.feasible") %> + + <%= check_box_tag :second_filter, "selected" %> + <%= t("#{i18n_namespace}.filters.selected") %> + + <%= check_box_tag :second_filter, "undecided" %> + <%= t("#{i18n_namespace}.filters.undecided") %> + + <%= check_box_tag :second_filter, "unfeasible" %> + <%= t("#{i18n_namespace}.filters.unfeasible") %> + +
+ <%= text_field_tag :max_per_heading %> + <%= t("#{i18n_namespace}.filters.max_per_heading") %> +
+ + <%= submit_tag t("#{i18n_namespace}.filters.button"), class: "button small float-right" %> + <% end %> +
diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb index e86402fd5..6deafed19 100644 --- a/app/views/admin/budget_investments/index.html.erb +++ b/app/views/admin/budget_investments/index.html.erb @@ -1,21 +1,21 @@

<%= @budget.name %> - <%= t("admin.budget_investments.index.title") %>

- <%= form_tag admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false do %> + <%= form_tag(admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false) do %>
<%= select_tag :administrator_id, - options_for_select(admin_select_options, params[:administrator_id]), - { prompt: t("admin.budget_investments.index.administrator_filter_all"), - label: false, - class: "js-submit-on-change" } %> + options_for_select(admin_select_options, params[:administrator_id]), + { prompt: t("admin.budget_investments.index.administrator_filter_all"), + label: false, + class: "js-submit-on-change" } %>
<%= select_tag :valuator_id, - options_for_select(valuator_select_options, params[:valuator_id]), - { prompt: t("admin.budget_investments.index.valuator_filter_all"), - label: false, - class: "js-submit-on-change" } %> + options_for_select(valuator_select_options, params[:valuator_id]), + { prompt: t("admin.budget_investments.index.valuator_filter_all"), + label: false, + class: "js-submit-on-change" } %>
@@ -36,8 +36,10 @@ <% end %>
-<%= render '/shared/filter_subnav', i18n_namespace: "admin.budget_investments.index" %> +<%= render "advanced_filters", i18n_namespace: "admin.budget_investments.index" %> + +<%= render "/shared/filter_subnav", i18n_namespace: "admin.budget_investments.index" %>
- <%= render '/admin/budget_investments/investments' %> + <%= render "investments" %>
diff --git a/app/views/admin/budget_investments/index.js.erb b/app/views/admin/budget_investments/index.js.erb new file mode 100644 index 000000000..dc3a8d67a --- /dev/null +++ b/app/views/admin/budget_investments/index.js.erb @@ -0,0 +1 @@ +$("#investments").html('<%= j render("admin/budget_investments/investments") %>'); diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 16f599c8b..b6918bc8d 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -144,9 +144,14 @@ en: valuating: Under valuation valuation_finished: Valuation finished valuation_finished_feasible: Val. fin. Feasible + feasible: Feasible selected: Selected + undecided: Undecided + unfeasible: Unfeasible + max_per_heading: Max. supports per heading winners: Winners all: All + button: Filter download_current_selection: "Download current selection" no_budget_investments: "There are no investment projects." title: Investment projects diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 07fe9340a..c3bc13a0d 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -144,9 +144,14 @@ es: valuating: En evaluación valuation_finished: Evaluación finalizada valuation_finished_feasible: Viables - selected: Seleccionadas + feasible: Viables + selected: Seleccionados + undecided: Sin decidir + unfeasible: Inviables + max_per_heading: Corte por partida winners: Ganadoras all: Todas + button: Filtrar download_current_selection: "Descargar selección actual" no_budget_investments: "No hay proyectos de gasto." title: Proyectos de gasto From e92a67a206ec2d3086ee7ae179fd597fa56cf79f Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 18 Jan 2018 21:26:06 -0400 Subject: [PATCH 2/9] Simplify filters navbar on Admin::Budget::Investment --- .../admin/budget_investments_controller.rb | 14 +++++++------- config/locales/en/admin.yml | 7 +------ config/locales/es/admin.yml | 7 +------ 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index 7a57c8814..eb2125aa1 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -3,8 +3,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController include FeatureFlags feature_flag :budgets - has_filters(%w{valuation_open without_admin managed valuating valuation_finished - valuation_finished_feasible selected winners all}, + has_filters(%w{without_admin valuation_finished all}, only: [:index, :toggle_selection]) before_action :load_budget @@ -60,16 +59,16 @@ class Admin::BudgetInvestmentsController < Admin::BaseController def budget_investment_params params.require(:budget_investment) - .permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, :valuation_tag_list, :incompatible, - :selected, valuator_ids: []) + .permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, :valuation_tag_list, + :incompatible, :selected, valuator_ids: []) end def load_budget - @budget = Budget.includes(:groups).find params[:budget_id] + @budget = Budget.includes(:groups).find(params[:budget_id]) end def load_investment - @investment = Budget::Investment.where(budget_id: @budget.id).find params[:id] + @investment = Budget::Investment.where(budget_id: @budget.id).find(params[:id]) end def load_admins @@ -77,7 +76,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController end def load_valuators - @valuators = Valuator.includes(:user).all.order("description ASC").order("users.email ASC") + @valuators = Valuator.includes(:user).all.order(description: :asc).order("users.email ASC") end def load_tags @@ -93,4 +92,5 @@ class Admin::BudgetInvestmentsController < Admin::BaseController @investment.set_tag_list_on(:valuation, budget_investment_params[:valuation_tag_list]) params[:budget_investment] = params[:budget_investment].except(:valuation_tag_list) end + end diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index b6918bc8d..d277508c7 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -138,19 +138,14 @@ en: valuator_filter_all: All valuators tags_filter_all: All tags filters: - valuation_open: Open + all: All without_admin: Without assigned admin - managed: Managed - valuating: Under valuation valuation_finished: Valuation finished - valuation_finished_feasible: Val. fin. Feasible feasible: Feasible selected: Selected undecided: Undecided unfeasible: Unfeasible max_per_heading: Max. supports per heading - winners: Winners - all: All button: Filter download_current_selection: "Download current selection" no_budget_investments: "There are no investment projects." diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index c3bc13a0d..ae5abc502 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -138,19 +138,14 @@ es: valuator_filter_all: Todos los evaluadores tags_filter_all: Todas las etiquetas filters: - valuation_open: Abiertas + all: Todos without_admin: Sin administrador - managed: Gestionando - valuating: En evaluación valuation_finished: Evaluación finalizada - valuation_finished_feasible: Viables feasible: Viables selected: Seleccionados undecided: Sin decidir unfeasible: Inviables max_per_heading: Corte por partida - winners: Ganadoras - all: Todas button: Filtrar download_current_selection: "Descargar selección actual" no_budget_investments: "No hay proyectos de gasto." From ff40d320288d7d558e58d9bda22a46dd6031fdca Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 18 Jan 2018 21:34:08 -0400 Subject: [PATCH 3/9] Add new filters to Admin::Budget::Investment navbar --- app/controllers/admin/budget_investments_controller.rb | 2 +- app/models/budget/investment.rb | 2 ++ config/locales/en/admin.yml | 2 ++ config/locales/es/admin.yml | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index eb2125aa1..2ad59159c 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -3,7 +3,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController include FeatureFlags feature_flag :budgets - has_filters(%w{without_admin valuation_finished all}, + has_filters(%w{all without_admin without_valuator under_valuation valuation_finished}, only: [:index, :toggle_selection]) before_action :load_budget diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 21cdab879..5534c7d00 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -53,6 +53,8 @@ class Budget scope :valuation_open, -> { where(valuation_finished: false) } scope :without_admin, -> { valuation_open.where(administrator_id: nil) } + scope :without_valuator, -> { valuation_open.where(valuator_assignments_count: 0) } + scope :under_valuation, -> { valuation_open.where("valuator_assignments_count > 0 AND administrator_id IS NOT ?", nil) } scope :managed, -> { valuation_open.where(valuator_assignments_count: 0).where("administrator_id IS NOT ?", nil) } scope :valuating, -> { valuation_open.where("valuator_assignments_count > 0") } scope :valuation_finished, -> { where(valuation_finished: true) } diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index d277508c7..fd62030ee 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -140,6 +140,8 @@ en: filters: all: All without_admin: Without assigned admin + without_valuator: Without assigned valuator + under_valuation: Under valuation valuation_finished: Valuation finished feasible: Feasible selected: Selected diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index ae5abc502..907fd251f 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -140,6 +140,8 @@ es: filters: all: Todos without_admin: Sin administrador + without_valuator: Sin evaluador + under_valuation: En evaluación valuation_finished: Evaluación finalizada feasible: Viables selected: Seleccionados From 3826f040c290704bf9255157b917049c2864e2e9 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 18 Jan 2018 21:40:23 -0400 Subject: [PATCH 4/9] Add missing 'tbody' HTML tag to investments partial --- .../budget_investments/_investments.html.erb | 149 +++++++++--------- 1 file changed, 77 insertions(+), 72 deletions(-) diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb index a60e2ac11..e3cea1026 100644 --- a/app/views/admin/budget_investments/_investments.html.erb +++ b/app/views/admin/budget_investments/_investments.html.erb @@ -16,84 +16,89 @@ <%= t("admin.budget_investments.index.table_feasibility") %> <%= t("admin.budget_investments.index.table_valuation_finished") %> <%= t("admin.budget_investments.index.table_selection") %> - <% if params[:filter] == 'selected' %> + <% if params[:filter] == "selected" %> <%= t("admin.budget_investments.index.table_incompatible") %> <% end %> - <% @investments.each do |investment| %> - - - <%= investment.id %> - - - <%= link_to investment.title, - admin_budget_budget_investment_path(budget_id: @budget.id, - id: investment.id, - params: Budget::Investment.filter_params(params)), - target: "_blank" %> - - - <%= investment.total_votes %> - - - <% if investment.administrator.present? %> - - <%= investment.administrator.name %> - - <% else %> - <%= t("admin.budget_investments.index.no_admin_assigned") %> - <% end %> - - - <% if investment.valuators.size == 0 %> - <%= t("admin.budget_investments.index.no_valuators_assigned") %> - <% else %> - <%= investment.valuators.collect(&:description_or_name).join(', ') %> - <% end %> - - - <%= investment.heading.name %> - - - <%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}", - price: investment.formatted_price) - %> - - - <%= investment.valuation_finished? ? t('shared.yes'): t('shared.no') %> - - - <% if investment.selected? %> - <%= link_to_unless investment.budget.finished?, - t("admin.budget_investments.index.selected"), - toggle_selection_admin_budget_budget_investment_path(@budget, - investment, - filter: params[:filter], - page: params[:page]), - method: :patch, - remote: true, - class: "button small expanded" %> - <% elsif investment.feasible? && investment.valuation_finished? %> - <%= link_to_unless investment.budget.finished?, - t("admin.budget_investments.index.select"), - toggle_selection_admin_budget_budget_investment_path(@budget, - investment, - filter: params[:filter], - page: params[:page]), - method: :patch, - remote: true, - class: "button small hollow expanded" %> - <% end %> - - <% if params[:filter] == 'selected' %> - - <%= investment.incompatible? ? t('shared.yes'): t('shared.no') %> + + <% @investments.each do |investment| %> + + + <%= investment.id %> - <% end %> - - <% end %> + + <%= link_to investment.title, + admin_budget_budget_investment_path(budget_id: @budget.id, + id: investment.id, + params: Budget::Investment.filter_params(params)), + target: "_blank" %> + + + <%= investment.total_votes %> + + + <% if investment.administrator.present? %> + + <%= investment.administrator.name %> + + <% else %> + <%= t("admin.budget_investments.index.no_admin_assigned") %> + <% end %> + + + <% if investment.valuators.size.zero? %> + <%= t("admin.budget_investments.index.no_valuators_assigned") %> + <% else %> + <%= investment.valuators.collect(&:description_or_name).join(", ") %> + <% end %> + + + <%= investment.heading.name %> + + + <%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}", + price: investment.formatted_price) %> + + + <%= investment.valuation_finished? ? t("shared.yes"): t("shared.no") %> + + + <% if investment.selected? %> + <%= link_to_unless investment.budget.finished?, + t("admin.budget_investments.index.selected"), + toggle_selection_admin_budget_budget_investment_path(@budget, + investment, + filter: params[:filter], + second_filter: params[:second_filter], + max_per_heading: params[:max_per_heading], + page: params[:page]), + method: :patch, + remote: true, + class: "button small expanded" %> + <% elsif investment.feasible? && investment.valuation_finished? %> + <%= link_to_unless investment.budget.finished?, + t("admin.budget_investments.index.select"), + toggle_selection_admin_budget_budget_investment_path(@budget, + investment, + filter: params[:filter], + second_filter: params[:second_filter], + max_per_heading: params[:max_per_heading], + page: params[:page]), + method: :patch, + remote: true, + class: "button small hollow expanded" %> + <% end %> + + <% if params[:filter] == "selected" %> + + <%= investment.incompatible? ? t("shared.yes"): t("shared.no") %> + + <% end %> + + <% end %> + <%= paginate @investments %> From a085f471df357482a8fed3585c90ea78c7481bac Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Thu, 18 Jan 2018 21:44:07 -0400 Subject: [PATCH 5/9] Replace 'selection' header on investments partial with 'selected' --- config/locales/en/admin.yml | 2 +- config/locales/es/admin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index fd62030ee..295037867 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -170,7 +170,7 @@ en: table_geozone: "Scope of operation" table_feasibility: "Feasibility" table_valuation_finished: "Val. Fin." - table_selection: "Selection" + table_selection: "Selected" table_incompatible: "Incompatible" show: assigned_admin: Assigned administrator diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 907fd251f..4948943d2 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -169,7 +169,7 @@ es: table_geozone: "Ámbito de actuación" table_feasibility: "Viabilidad" table_valuation_finished: "Ev. Fin." - table_selection: "Selección" + table_selection: "Seleccionado" table_incompatible: "Incompatible" show: assigned_admin: Administrador asignado From dddf026a597d9d8d55728c585956b966b9d50357 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 19 Jan 2018 00:32:04 -0400 Subject: [PATCH 6/9] Adapt Admin::Budget::Investment failing specs to new filter UI --- .../features/admin/budget_investments_spec.rb | 68 ++++++++----------- spec/features/admin/budgets_spec.rb | 2 +- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 627824045..13407f202 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -187,12 +187,11 @@ feature 'Admin budget investments' do end scenario "Current filter is properly highlighted" do - filters_links = {'valuation_open' => 'Open', - 'without_admin' => 'Without assigned admin', - 'managed' => 'Managed', - 'valuating' => 'Under valuation', - 'valuation_finished' => 'Valuation finished', - 'all' => 'All'} + filters_links = { 'all' => 'All', + 'without_admin' => 'Without assigned admin', + 'without_valuator' => 'Without assigned valuator', + 'under_valuation' => 'Under valuation', + 'valuation_finished' => 'Valuation finished' } visit admin_budget_budget_investments_path(budget_id: @budget.id) @@ -213,36 +212,26 @@ feature 'Admin budget investments' do scenario "Filtering by assignment status" do assigned = create(:budget_investment, title: "Assigned idea", budget: @budget, administrator: create(:administrator)) valuating = create(:budget_investment, title: "Evaluating...", budget: @budget) - valuating.valuators << create(:valuator) - - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_open') - - expect(page).to have_content("Assigned idea") - expect(page).to have_content("Evaluating...") + valuating.valuators.push(create(:valuator)) visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_admin') expect(page).to have_content("Evaluating...") expect(page).not_to have_content("Assigned idea") - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'managed') + visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_valuator') expect(page).to have_content("Assigned idea") expect(page).not_to have_content("Evaluating...") end scenario "Filtering by valuation status" do - valuating = create(:budget_investment, budget: @budget, title: "Ongoing valuation") + valuating = create(:budget_investment, budget: @budget, title: "Ongoing valuation", administrator: create(:administrator)) valuated = create(:budget_investment, budget: @budget, title: "Old idea", valuation_finished: true) - valuating.valuators << create(:valuator) - valuated.valuators << create(:valuator) + valuating.valuators.push(create(:valuator)) + valuated.valuators.push(create(:valuator)) - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_open') - - expect(page).to have_content("Ongoing valuation") - expect(page).not_to have_content("Old idea") - - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuating') + visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'under_valuation') expect(page).to have_content("Ongoing valuation") expect(page).not_to have_content("Old idea") @@ -575,7 +564,7 @@ feature 'Admin budget investments' do let!(:selected_bi) { create(:budget_investment, :selected, budget: @budget, title: "Selected project") } let!(:winner_bi) { create(:budget_investment, :winner, budget: @budget, title: "Winner project") } - scenario "Filtering by valuation and selection" do + scenario "Filtering by valuation and selection", :js do visit admin_budget_budget_investments_path(@budget) within('#filter-subnav') { click_link 'Valuation finished' } @@ -585,31 +574,34 @@ feature 'Admin budget investments' do expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) - within('#filter-subnav') { click_link 'Val. fin. Feasible' } + within('#advanced-filters') { find(:css, "#second_filter[value='feasible']").set(true) } + click_button 'Filter' + expect(page).not_to have_content(unfeasible_bi.title) expect(page).not_to have_content(feasible_bi.title) expect(page).to have_content(feasible_vf_bi.title) expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) - within('#filter-subnav') { click_link 'Selected' } + within('#advanced-filters') { find(:css, "#second_filter[value='selected']").set(true) } + click_button 'Filter' + expect(page).not_to have_content(unfeasible_bi.title) expect(page).not_to have_content(feasible_bi.title) expect(page).not_to have_content(feasible_vf_bi.title) expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) - within('#filter-subnav') { click_link 'Winners' } - expect(page).not_to have_content(unfeasible_bi.title) - expect(page).not_to have_content(feasible_bi.title) - expect(page).not_to have_content(feasible_vf_bi.title) - expect(page).not_to have_content(selected_bi.title) - expect(page).to have_content(winner_bi.title) + # within('#filter-subnav') { click_link 'Winners' } + # expect(page).not_to have_content(unfeasible_bi.title) + # expect(page).not_to have_content(feasible_bi.title) + # expect(page).not_to have_content(feasible_vf_bi.title) + # expect(page).not_to have_content(selected_bi.title) + # expect(page).to have_content(winner_bi.title) end scenario "Showing the selection buttons", :js do visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'All' } within("#budget_investment_#{unfeasible_bi.id}") do expect(page).not_to have_link('Select') @@ -634,14 +626,14 @@ feature 'Admin budget investments' do scenario "Selecting an investment", :js do visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'All' } within("#budget_investment_#{feasible_vf_bi.id}") do click_link('Select') expect(page).to have_link('Selected') end - within('#filter-subnav') { click_link 'Selected' } + within('#advanced-filters') { find(:css, "#second_filter[value='selected']").set(true) } + click_button 'Filter' within("#budget_investment_#{feasible_vf_bi.id}") do expect(page).not_to have_link('Select') @@ -651,7 +643,8 @@ feature 'Admin budget investments' do scenario "Unselecting an investment", :js do visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'Selected' } + within('#advanced-filters') { find(:css, "#second_filter[value='selected']").set(true) } + click_button 'Filter' expect(page).to have_content('There are 2 investments') @@ -662,7 +655,7 @@ feature 'Admin budget investments' do expect(page).not_to have_content(selected_bi.title) expect(page).to have_content('There is 1 investment') - within('#filter-subnav') { click_link 'All' } + visit admin_budget_budget_investments_path(@budget) within("#budget_investment_#{selected_bi.id}") do expect(page).to have_link('Select') @@ -678,13 +671,12 @@ feature 'Admin budget investments' do price: 100) valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@val.org')) - investment.valuators << valuator + investment.valuators.push(valuator) admin = create(:administrator, user: create(:user, username: 'Gema')) investment.update(administrator_id: admin.id) visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'All' } click_link "Download current selection" diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 7da02b559..07915e999 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -177,7 +177,7 @@ feature 'Admin budgets' do context "Calculate Budget's Winner Investments" do - scenario 'For a Budget in reviewing balloting' do + xscenario 'For a Budget in reviewing balloting' do budget = create(:budget, phase: 'reviewing_ballots') group = create(:budget_group, budget: budget) heading = create(:budget_heading, group: group, price: 4) From a79e60ecd1a03594a78d636e7173700a73d71026 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 19 Jan 2018 00:46:30 -0400 Subject: [PATCH 7/9] Add spec for Admin::Budget::Investment 'max_per_heading' filter --- .../features/admin/budget_investments_spec.rb | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 13407f202..86336b02c 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -281,6 +281,60 @@ feature 'Admin budget investments' do expect(page).to have_select("tag_name", options: ["All tags", "Hospitals", "Teachers"]) end + scenario "Limiting by max number of investments per heading", :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 + + 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 + + fill_in "max_per_heading", with: 5 + 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 + end + end context 'Show' do From 102789661773e558cedc99fd072d3b0faf873e47 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 19 Jan 2018 09:45:02 -0400 Subject: [PATCH 8/9] Reenable 'winners' tab under Admin::Budget::Investment --- .../admin/budget_investments_controller.rb | 3 ++- config/locales/en/admin.yml | 1 + config/locales/es/admin.yml | 1 + spec/features/admin/budget_investments_spec.rb | 12 ++++++------ spec/features/admin/budgets_spec.rb | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index 2ad59159c..8c45d7c9c 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -3,7 +3,8 @@ class Admin::BudgetInvestmentsController < Admin::BaseController include FeatureFlags feature_flag :budgets - has_filters(%w{all without_admin without_valuator under_valuation valuation_finished}, + has_filters(%w{all without_admin without_valuator under_valuation + valuation_finished winners}, only: [:index, :toggle_selection]) before_action :load_budget diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 295037867..059cfaa9e 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -148,6 +148,7 @@ en: undecided: Undecided unfeasible: Unfeasible max_per_heading: Max. supports per heading + winners: Winners button: Filter download_current_selection: "Download current selection" no_budget_investments: "There are no investment projects." diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 4948943d2..741cc7197 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -148,6 +148,7 @@ es: undecided: Sin decidir unfeasible: Inviables max_per_heading: Corte por partida + winners: Ganadores button: Filtrar download_current_selection: "Descargar selección actual" no_budget_investments: "No hay proyectos de gasto." diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 86336b02c..05e3f905d 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -646,12 +646,12 @@ feature 'Admin budget investments' do expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) - # within('#filter-subnav') { click_link 'Winners' } - # expect(page).not_to have_content(unfeasible_bi.title) - # expect(page).not_to have_content(feasible_bi.title) - # expect(page).not_to have_content(feasible_vf_bi.title) - # expect(page).not_to have_content(selected_bi.title) - # expect(page).to have_content(winner_bi.title) + within('#filter-subnav') { click_link 'Winners' } + expect(page).not_to have_content(unfeasible_bi.title) + expect(page).not_to have_content(feasible_bi.title) + expect(page).not_to have_content(feasible_vf_bi.title) + expect(page).not_to have_content(selected_bi.title) + expect(page).to have_content(winner_bi.title) end scenario "Showing the selection buttons", :js do diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 07915e999..7da02b559 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -177,7 +177,7 @@ feature 'Admin budgets' do context "Calculate Budget's Winner Investments" do - xscenario 'For a Budget in reviewing balloting' do + scenario 'For a Budget in reviewing balloting' do budget = create(:budget, phase: 'reviewing_ballots') group = create(:budget_group, budget: budget) heading = create(:budget_heading, group: group, price: 4) From 3f6a9187ec46bb42db793acaf3732138970a2879 Mon Sep 17 00:00:00 2001 From: Angel Perez Date: Fri, 19 Jan 2018 12:18:43 -0400 Subject: [PATCH 9/9] Add 'current applied filters' message to investments partial --- .../_filters_description.html.erb | 13 +++++++++++++ .../admin/budget_investments/_investments.html.erb | 5 ++++- config/locales/en/admin.yml | 2 ++ config/locales/es/admin.yml | 2 ++ 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 app/views/admin/budget_investments/_filters_description.html.erb diff --git a/app/views/admin/budget_investments/_filters_description.html.erb b/app/views/admin/budget_investments/_filters_description.html.erb new file mode 100644 index 000000000..43e48408f --- /dev/null +++ b/app/views/admin/budget_investments/_filters_description.html.erb @@ -0,0 +1,13 @@ +<% if params[:filter].present? && params[:second_filter].present? %> +

<%= t("#{i18n_namespace}.filters.two_filters_html", + filter: t("#{i18n_namespace}.filters.#{params[:filter]}"), + second_filter: t("#{i18n_namespace}.filters.#{params[:second_filter]}")) %>

+ +<% elsif params[:filter].present? %> +

<%= t("#{i18n_namespace}.filters.one_filter_html", + filter: t("#{i18n_namespace}.filters.#{params[:filter]}")) %>

+ +<% elsif params[:second_filter].present? %> +

<%= t("#{i18n_namespace}.filters.one_filter_html", + filter: t("#{i18n_namespace}.filters.#{params[:second_filter]}")) %>

+<% end %> diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb index e3cea1026..3456021db 100644 --- a/app/views/admin/budget_investments/_investments.html.erb +++ b/app/views/admin/budget_investments/_investments.html.erb @@ -3,7 +3,10 @@ class: "float-right small" %> <% if @investments.any? %> -

<%= page_entries_info @investments %>

+

<%= page_entries_info @investments %>


+ + <%= render "filters_description", i18n_namespace: "admin.budget_investments.index" %> + diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 059cfaa9e..ea30543d9 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -150,6 +150,8 @@ en: max_per_heading: Max. supports per heading winners: Winners button: Filter + one_filter_html: "Current applied filter: %{filter}" + two_filters_html: "Current applied filters: %{filter}, %{second_filter}" download_current_selection: "Download current selection" no_budget_investments: "There are no investment projects." title: Investment projects diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 741cc7197..36dfb6be6 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -150,6 +150,8 @@ es: max_per_heading: Corte por partida winners: Ganadores button: Filtrar + one_filter_html: "Filtro en uso: %{filter}" + two_filters_html: "Filtros en uso: %{filter}, %{second_filter}" download_current_selection: "Descargar selección actual" no_budget_investments: "No hay proyectos de gasto." title: Proyectos de gasto