diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb
index 8c45d7c9c..9bf4d4610 100644
--- a/app/controllers/admin/budget_investments_controller.rb
+++ b/app/controllers/admin/budget_investments_controller.rb
@@ -52,9 +52,21 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
private
+ def sort_by(params)
+ if params.present? && Budget::Investment::SORTING_OPTIONS.include?(params)
+ "#{params == 'supports' ? 'cached_votes_up' : params} ASC"
+ else
+ "cached_votes_up DESC, created_at DESC"
+ end
+ end
+
def load_investments
- @investments = Budget::Investment.scoped_filter(params, @current_filter)
- .order(cached_votes_up: :desc, created_at: :desc)
+ if params[:project_title].present?
+ @investments = Budget::Investment.where("title ILIKE ?", "%#{params[:project_title].strip}%")
+ else
+ @investments = Budget::Investment.scoped_filter(params, @current_filter)
+ .order(sort_by(params[:sort_by]))
+ end
@investments = @investments.page(params[:page]) unless request.format.csv?
end
diff --git a/app/helpers/budget_investments_helper.rb b/app/helpers/budget_investments_helper.rb
new file mode 100644
index 000000000..40db91c1f
--- /dev/null
+++ b/app/helpers/budget_investments_helper.rb
@@ -0,0 +1,5 @@
+module BudgetInvestmentsHelper
+ def budget_investments_sorting_options
+ Budget::Investment::SORTING_OPTIONS.map { |so| [t("admin.budget_investments.index.sort_by.#{so}"), so] }
+ end
+end
diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb
index 5534c7d00..58674be9b 100644
--- a/app/models/budget/investment.rb
+++ b/app/models/budget/investment.rb
@@ -2,6 +2,8 @@ require 'csv'
class Budget
class Investment < ActiveRecord::Base
+ SORTING_OPTIONS = %w(id title supports).freeze
+
include Rails.application.routes.url_helpers
include Measurable
include Sanitizable
diff --git a/app/views/admin/budget_investments/_advanced_filters.html.erb b/app/views/admin/budget_investments/_advanced_filters.html.erb
index 7f6e7fe6a..5042bbfc8 100644
--- a/app/views/admin/budget_investments/_advanced_filters.html.erb
+++ b/app/views/admin/budget_investments/_advanced_filters.html.erb
@@ -7,6 +7,7 @@
<%= form_tag(admin_budget_budget_investments_path(budget: @budget,
filter: params[:filter],
+ sort_by: params[:sort_by],
second_filter: params[:second_filter],
max_per_heading: params[:max_per_heading],
page: 1), method: :get, remote: true, enforce_utf8: false) do %>
@@ -38,7 +39,7 @@
- <%= submit_tag t("#{i18n_namespace}.filters.button"), class: "button expanded" %>
+ <%= submit_tag t("admin.budget_investments.index.buttons.filter"), class: "button expanded" %>
<% end %>
diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb
index 3456021db..51c1c07d6 100644
--- a/app/views/admin/budget_investments/_investments.html.erb
+++ b/app/views/admin/budget_investments/_investments.html.erb
@@ -1,3 +1,12 @@
+<%= form_tag(admin_budget_budget_investments_path(budget: @budget), method: :get) do %>
+
+ <%= select_tag :sort_by, options_for_select(budget_investments_sorting_options, params[:sort_by]),
+ { prompt: t("admin.budget_investments.index.sort_by.placeholder"),
+ label: false,
+ class: "js-submit-on-change" } %>
+
+<% end %>
+
<%= link_to t("admin.budget_investments.index.download_current_selection"),
admin_budget_budget_investments_path(csv_params),
class: "float-right small" %>
@@ -74,6 +83,7 @@
toggle_selection_admin_budget_budget_investment_path(@budget,
investment,
filter: params[:filter],
+ sort_by: params[:sort_by],
second_filter: params[:second_filter],
max_per_heading: params[:max_per_heading],
page: params[:page]),
@@ -86,6 +96,7 @@
toggle_selection_admin_budget_budget_investment_path(@budget,
investment,
filter: params[:filter],
+ sort_by: params[:sort_by],
second_filter: params[:second_filter],
max_per_heading: params[:max_per_heading],
page: params[:page]),
diff --git a/app/views/admin/budget_investments/_search_form.html.erb b/app/views/admin/budget_investments/_search_form.html.erb
new file mode 100644
index 000000000..df73f123a
--- /dev/null
+++ b/app/views/admin/budget_investments/_search_form.html.erb
@@ -0,0 +1,12 @@
+
+ <%= form_for(Budget::Investment.new, url: admin_budget_budget_investments_path(budget: @budget),
+ method: :get,
+ remote: true) do |f| %>
+
+ <% end %>
+
diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb
index b0eed56aa..522382939 100644
--- a/app/views/admin/budget_investments/index.html.erb
+++ b/app/views/admin/budget_investments/index.html.erb
@@ -1,5 +1,7 @@
<%= @budget.name %> - <%= t("admin.budget_investments.index.title") %>
+<%= render "search_form" %>
+
<%= form_tag(admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false) do %>
<%= select_tag :administrator_id,
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml
index 60b3c5fe4..237c0f91a 100644
--- a/config/locales/en/admin.yml
+++ b/config/locales/en/admin.yml
@@ -138,6 +138,12 @@ en:
valuator_filter_all: All valuators
tags_filter_all: All tags
advanced_filters: Advanced filters
+ placeholder: Search projects
+ sort_by:
+ placeholder: Sort by
+ id: ID
+ title: Title
+ supports: Supports
filters:
all: All
without_admin: Without assigned admin
@@ -150,9 +156,11 @@ en:
unfeasible: Unfeasible
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}"
+ buttons:
+ search: Search
+ filter: 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 865a2e3ce..44f89facd 100644
--- a/config/locales/es/admin.yml
+++ b/config/locales/es/admin.yml
@@ -138,6 +138,12 @@ es:
valuator_filter_all: Todos los evaluadores
tags_filter_all: Todas las etiquetas
advanced_filters: Filtros avanzados
+ placeholder: Buscar proyectos
+ sort_by:
+ placeholder: Ordenar por
+ id: ID
+ title: Título
+ supports: Apoyos
filters:
all: Todos
without_admin: Sin administrador
@@ -150,9 +156,11 @@ es:
unfeasible: Inviables
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}"
+ buttons:
+ search: Buscar
+ filter: Filtrar
download_current_selection: "Descargar selección actual"
no_budget_investments: "No hay proyectos de gasto."
title: Proyectos de gasto
diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb
index 14de19dfe..8bf28e313 100644
--- a/spec/features/admin/budget_investments_spec.rb
+++ b/spec/features/admin/budget_investments_spec.rb
@@ -338,6 +338,57 @@ feature 'Admin budget investments' do
end
+ context 'Search' do
+ background do
+ @budget = create(:budget)
+ @investment_1 = create(:budget_investment, title: "Some investment", budget: @budget)
+ @investment_2 = create(:budget_investment, title: "Some other investment", budget: @budget)
+ end
+
+ scenario "Search investments by title" do
+ visit admin_budget_budget_investments_path(@budget)
+
+ expect(page).to have_content(@investment_1.title)
+ expect(page).to have_content(@investment_2.title)
+
+ fill_in 'project_title', with: 'Some investment'
+ click_button 'Search'
+
+ expect(page).to have_content(@investment_1.title)
+ expect(page).to_not have_content(@investment_2.title)
+ end
+ end
+
+ context 'Sorting' do
+ background do
+ @budget = create(:budget)
+ @investment_1 = create(:budget_investment, title: "BBBB", cached_votes_up: 50, budget: @budget)
+ @investment_2 = create(:budget_investment, title: "AAAA", cached_votes_up: 25, budget: @budget)
+ @investment_3 = create(:budget_investment, title: "CCCC", cached_votes_up: 10, budget: @budget)
+ end
+
+ scenario 'Sort by ID' do
+ visit admin_budget_budget_investments_path(@budget, sort_by: 'id')
+
+ expect(@investment_1.title).to appear_before(@investment_2.title)
+ expect(@investment_2.title).to appear_before(@investment_3.title)
+ end
+
+ scenario 'Sort by title' do
+ visit admin_budget_budget_investments_path(@budget, sort_by: 'title')
+
+ expect(@investment_2.title).to appear_before(@investment_1.title)
+ expect(@investment_1.title).to appear_before(@investment_3.title)
+ end
+
+ scenario 'Sort by supports' do
+ visit admin_budget_budget_investments_path(@budget, sort_by: 'supports')
+
+ expect(@investment_3.title).to appear_before(@investment_2.title)
+ expect(@investment_2.title).to appear_before(@investment_1.title)
+ end
+ end
+
context 'Show' do
background do
@administrator = create(:administrator, user: create(:user, username: 'Ana', email: 'ana@admins.org'))