diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb
index 7eb1b1291..469b09255 100644
--- a/app/controllers/budgets/investments_controller.rb
+++ b/app/controllers/budgets/investments_controller.rb
@@ -20,10 +20,11 @@ module Budgets
has_orders %w{most_voted newest oldest}, only: :show
has_orders ->(c) { c.instance_variable_get(:@budget).investments_orders }, only: :index
- has_filters %w{not_unfeasible feasible unfeasible unselected selected}, only: [:index, :show]
+ has_filters %w{not_unfeasible feasible unfeasible unselected selected}, only: [:index, :show, :suggest]
invisible_captcha only: [:create, :update], honeypot: :subtitle, scope: :budget_investment
+ helper_method :resource_model, :resource_name
respond_to :html, :js
def index
@@ -70,8 +71,22 @@ module Budgets
end
end
+ def suggest
+ @resource_path_method = :namespaced_budget_investment_path
+ @resource_relation = resource_model.where(budget: @budget).apply_filters_and_search(@budget, params, @current_filter)
+ super
+ end
+
private
+ def resource_model
+ Budget::Investment
+ end
+
+ def resource_name
+ "budget_investment"
+ end
+
def load_investment_votes(investments)
@investment_votes = current_user ? current_user.budget_investment_votes(investments) : {}
end
diff --git a/app/controllers/concerns/commentable_actions.rb b/app/controllers/concerns/commentable_actions.rb
index 287f2d418..489d1857c 100644
--- a/app/controllers/concerns/commentable_actions.rb
+++ b/app/controllers/concerns/commentable_actions.rb
@@ -34,7 +34,7 @@ module CommentableActions
def suggest
@limit = 5
- @resources = @search_terms.present? ? resource_model.search(@search_terms) : nil
+ @resources = @search_terms.present? ? resource_relation.search(@search_terms) : nil
end
def create
diff --git a/app/controllers/concerns/polymorphic.rb b/app/controllers/concerns/polymorphic.rb
index 10d64698d..6ac4b5c1c 100644
--- a/app/controllers/concerns/polymorphic.rb
+++ b/app/controllers/concerns/polymorphic.rb
@@ -10,6 +10,10 @@ module Polymorphic
@resource_name ||= resource_model.to_s.downcase
end
+ def resource_relation
+ @resource_relation ||= resource_model.all
+ end
+
def set_resource_instance
instance_variable_set("@#{resource_name}", @resource)
end
diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb
index 6a8ef594c..16747c8a7 100644
--- a/app/models/abilities/common.rb
+++ b/app/models/abilities/common.rb
@@ -46,6 +46,7 @@ module Abilities
can :create, SpendingProposal
can :create, Budget::Investment, budget: { phase: "accepting" }
+ can :suggest, Budget::Investment, budget: { phase: "accepting" }
can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id
can :vote, Budget::Investment, budget: { phase: "selecting" }
can [:show, :create], Budget::Ballot, budget: { phase: "balloting" }
diff --git a/app/views/budgets/investments/_form.html.erb b/app/views/budgets/investments/_form.html.erb
index 12f91f486..28b47d726 100644
--- a/app/views/budgets/investments/_form.html.erb
+++ b/app/views/budgets/investments/_form.html.erb
@@ -7,8 +7,9 @@
- <%= f.text_field :title, maxlength: SpendingProposal.title_max_length %>
+ <%= f.text_field :title, maxlength: SpendingProposal.title_max_length, data: { js_suggest_result: "js_suggest_result", js_suggest: "#js-suggest", js_url: suggest_budget_investments_path(@budget) }%>
+
<%= f.invisible_captcha :subtitle %>
diff --git a/app/views/budgets/investments/suggest.js.erb b/app/views/budgets/investments/suggest.js.erb
new file mode 100644
index 000000000..d49120ed2
--- /dev/null
+++ b/app/views/budgets/investments/suggest.js.erb
@@ -0,0 +1 @@
+<%= render "shared/suggest" %>
diff --git a/app/views/shared/_suggest.html.erb b/app/views/shared/_suggest.html.erb
index 03d14296c..d50f67056 100644
--- a/app/views/shared/_suggest.html.erb
+++ b/app/views/shared/_suggest.html.erb
@@ -9,7 +9,7 @@
<% @resources.limit(@limit).each do |resource| %>
- - <%= link_to resource.title, resource %>
+ - <%= link_to resource.title, @resource_path_method.present? ? send(@resource_path_method, resource) : resource %>
<% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 342aaa455..7da965fe4 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -511,6 +511,12 @@ en:
other: "There are debates with the term '%{query}', you can participate in them instead of opening a new one."
message: "You are seeing %{limit} of %{count} debates containing the term '%{query}'"
see_all: "Ver todos"
+ budget_investment:
+ found:
+ one: "There is an investment with the term '%{query}', you can participate in it instead of opening a new one."
+ other: "There are investments with the term '%{query}', you can participate in them instead of opening a new one."
+ message: "You are seeing %{limit} of %{count} investments containing the term '%{query}'"
+ see_all: "See all"
proposal:
found:
one: "There is a proposal with the term '%{query}', you can contribute to it instead of creating a new"
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 9ff5d64c6..07c653669 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -511,6 +511,12 @@ es:
other: "Existen debates con el término '%{query}', puedes participar en ellos en vez de abrir uno nuevo."
message: "Estás viendo %{limit} de %{count} debates que contienen el término '%{query}'"
see_all: "Ver todos"
+ budget_investment:
+ found:
+ one: "Existe una propuesta de inversión con el término '%{query}', puedes participar en ella en vez de abrir una nueva."
+ other: "Existen propuestas de inversión con el término '%{query}', puedes participar en ellas en vez de abrir una nueva."
+ message: "Estás viendo %{limit} de %{count} propuestas de inversión que contienen el término '%{query}'"
+ see_all: "Ver todas"
proposal:
found:
one: "Existe una propuesta con el término '%{query}', puedes participar en ella en vez de abrir uno nuevo."
diff --git a/config/routes.rb b/config/routes.rb
index e0cb9c632..6cbd69c3a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -78,7 +78,8 @@ Rails.application.routes.draw do
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 { post :vote }
+ collection { get :suggest }
end
resource :ballot, only: :show, controller: "budgets/ballots" do
resources :lines, controller: "budgets/ballot/lines", only: [:create, :destroy]
diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb
index ef84cc6fc..b49fa8ddc 100644
--- a/spec/features/budgets/investments_spec.rb
+++ b/spec/features/budgets/investments_spec.rb
@@ -4,6 +4,7 @@ feature 'Budget Investments' do
let(:author) { create(:user, :level_two, username: 'Isabel') }
let(:budget) { create(:budget, name: "Big Budget") }
+ let(:other_budget) { create(:budget, name: "What a Budget!") }
let(:group) { create(:budget_group, name: "Health", budget: budget) }
let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) }
@@ -248,6 +249,56 @@ feature 'Budget Investments' do
expect(page).to have_content error_message
end
+ context 'Suggest' do
+ factory = :budget_investment
+
+ scenario 'Show up to 5 suggestions', :js do
+ login_as(author)
+
+ %w(first second third fourth fifth sixth).each do |ordinal|
+ create(factory, title: "#{ordinal.titleize} #{factory}, has search term", budget: budget)
+ end
+ create(factory, title: "This is the last #{factory}", budget: budget)
+
+ visit new_budget_investment_path(budget)
+ fill_in "budget_investment_title", with: "search"
+
+ within("div#js-suggest") do
+ expect(page).to have_content ("You are seeing 5 of 6 investments containing the term 'search'")
+ end
+ end
+
+ scenario 'No found suggestions', :js do
+ login_as(author)
+
+ %w(first second third fourth fifth sixth).each do |ordinal|
+ create(factory, title: "#{ordinal.titleize} #{factory}, has search term", budget: budget)
+ end
+
+ visit new_budget_investment_path(budget)
+ fill_in "budget_investment_title", with: "item"
+
+ within('div#js-suggest') do
+ expect(page).to_not have_content ('You are seeing')
+ end
+ end
+
+ scenario "Don't show suggestions from a different budget", :js do
+ login_as(author)
+
+ %w(first second third fourth fifth sixth).each do |ordinal|
+ create(factory, title: "#{ordinal.titleize} #{factory}, has search term", budget: budget)
+ end
+
+ visit new_budget_investment_path(other_budget)
+ fill_in "budget_investment_title", with: "search"
+
+ within('div#js-suggest') do
+ expect(page).to_not have_content ('You are seeing')
+ end
+ end
+ end
+
scenario 'Ballot is not visible' do
login_as(author)