Skip to content

Commit

Permalink
Merge pull request consuldemocracy#2344 from wairbut-m2c/aperez-inves…
Browse files Browse the repository at this point in the history
…tments-filters

Improvements for Admin::Budget::Investment filters
  • Loading branch information
MariaCheca committed Jan 23, 2018
2 parents d774116 + 7521f83 commit a1d83e4
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 142 deletions.
16 changes: 9 additions & 7 deletions app/controllers/admin/budget_investments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ 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{all without_admin without_valuator under_valuation
valuation_finished winners},
only: [:index, :toggle_selection])

before_action :load_budget
Expand All @@ -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'
Expand Down Expand Up @@ -59,24 +60,24 @@ def load_investments

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
@admins = Administrator.includes(:user).all
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
Expand All @@ -92,4 +93,5 @@ def set_valuation_tags
@investment.set_tag_list_on(:valuation, budget_investment_params[:valuation_tag_list])
params[:budget_investment] = params[:budget_investment].except(:valuation_tag_list)
end

end
37 changes: 31 additions & 6 deletions app/models/budget/investment.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'csv'

class Budget
class Investment < ActiveRecord::Base
require 'csv'
include Rails.application.routes.url_helpers
include Measurable
include Sanitizable
Expand Down Expand Up @@ -52,8 +53,10 @@ class Investment < ActiveRecord::Base

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 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") }
Expand Down Expand Up @@ -86,20 +89,42 @@ def url
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',
Expand Down
27 changes: 27 additions & 0 deletions app/views/admin/budget_investments/_advanced_filters.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div id="advanced-filters" class="callout primary">
<%= 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") %>

<div class="large-1">
<%= text_field_tag :max_per_heading %>
<%= t("#{i18n_namespace}.filters.max_per_heading") %>
</div>

<%= submit_tag t("#{i18n_namespace}.filters.button"), class: "button small float-right" %>
<% end %>
</div>
13 changes: 13 additions & 0 deletions app/views/admin/budget_investments/_filters_description.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<% if params[:filter].present? && params[:second_filter].present? %>
<p class="inline-block"><%= t("#{i18n_namespace}.filters.two_filters_html",
filter: t("#{i18n_namespace}.filters.#{params[:filter]}"),
second_filter: t("#{i18n_namespace}.filters.#{params[:second_filter]}")) %></p>

<% elsif params[:filter].present? %>
<p class="inline-block"><%= t("#{i18n_namespace}.filters.one_filter_html",
filter: t("#{i18n_namespace}.filters.#{params[:filter]}")) %></p>

<% elsif params[:second_filter].present? %>
<p class="inline-block"><%= t("#{i18n_namespace}.filters.one_filter_html",
filter: t("#{i18n_namespace}.filters.#{params[:second_filter]}")) %></p>
<% end %>
152 changes: 80 additions & 72 deletions app/views/admin/budget_investments/_investments.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
class: "float-right small" %>
<% if @investments.any? %>
<h3 class="inline-block"><%= page_entries_info @investments %></h3>
<h3 class="inline-block"><%= page_entries_info @investments %></h3><br>

<%= render "filters_description", i18n_namespace: "admin.budget_investments.index" %>

<table class="table-for-mobile">
<thead>
<tr>
Expand All @@ -16,84 +19,89 @@
<th><%= t("admin.budget_investments.index.table_feasibility") %></th>
<th class="text-center"><%= t("admin.budget_investments.index.table_valuation_finished") %></th>
<th class="text-center"><%= t("admin.budget_investments.index.table_selection") %></th>
<% if params[:filter] == 'selected' %>
<% if params[:filter] == "selected" %>
<th class="text-center"><%= t("admin.budget_investments.index.table_incompatible") %></th>
<% end %>
</tr>
</thead>

<% @investments.each do |investment| %>
<tr id="<%= dom_id(investment) %>" class="budget_investment">
<td class="text-right">
<strong><%= investment.id %></strong>
</td>
<td>
<%= link_to investment.title,
admin_budget_budget_investment_path(budget_id: @budget.id,
id: investment.id,
params: Budget::Investment.filter_params(params)),
target: "_blank" %>
</td>
<td class="text-center">
<%= investment.total_votes %>
</td>
<td class="small">
<% if investment.administrator.present? %>
<span title="<%= t('admin.budget_investments.index.assigned_admin') %>">
<%= investment.administrator.name %>
</span>
<% else %>
<%= t("admin.budget_investments.index.no_admin_assigned") %>
<% end %>
</td>
<td class="small">
<% if investment.valuators.size == 0 %>
<%= t("admin.budget_investments.index.no_valuators_assigned") %>
<% else %>
<%= investment.valuators.collect(&:description_or_name).join(', ') %>
<% end %>
</td>
<td class="small">
<%= investment.heading.name %>
</td>
<td class="small">
<%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}",
price: investment.formatted_price)
%>
</td>
<td class="small text-center">
<%= investment.valuation_finished? ? t('shared.yes'): t('shared.no') %>
</td>
<td class="small">
<% 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 %>
</td>
<% if params[:filter] == 'selected' %>
<tbody>
<% @investments.each do |investment| %>
<tr id="<%= dom_id(investment) %>" class="budget_investment">
<td class="text-right">
<strong><%= investment.id %></strong>
</td>
<td>
<%= link_to investment.title,
admin_budget_budget_investment_path(budget_id: @budget.id,
id: investment.id,
params: Budget::Investment.filter_params(params)),
target: "_blank" %>
</td>
<td class="text-center">
<%= investment.total_votes %>
</td>
<td class="small">
<% if investment.administrator.present? %>
<span title="<%= t('admin.budget_investments.index.assigned_admin') %>">
<%= investment.administrator.name %>
</span>
<% else %>
<%= t("admin.budget_investments.index.no_admin_assigned") %>
<% end %>
</td>
<td class="small">
<% if investment.valuators.size.zero? %>
<%= t("admin.budget_investments.index.no_valuators_assigned") %>
<% else %>
<%= investment.valuators.collect(&:description_or_name).join(", ") %>
<% end %>
</td>
<td class="small">
<%= investment.heading.name %>
</td>
<td class="small">
<%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}",
price: investment.formatted_price) %>
</td>
<td class="small text-center">
<%= investment.incompatible? ? t('shared.yes'): t('shared.no') %>
<%= investment.valuation_finished? ? t("shared.yes"): t("shared.no") %>
</td>
<% end %>
</tr>
<% end %>
<td class="small">
<% 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 %>
</td>
<% if params[:filter] == "selected" %>
<td class="small text-center">
<%= investment.incompatible? ? t("shared.yes"): t("shared.no") %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>

<%= paginate @investments %>
Expand Down
24 changes: 13 additions & 11 deletions app/views/admin/budget_investments/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
<h2 class="inline-block"><%= @budget.name %> - <%= t("admin.budget_investments.index.title") %></h2>

<div class="row margin">
<%= 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 %>
<div class="small-12 medium-3 column">
<%= 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" } %>
</div>

<div class="small-12 medium-3 column">
<%= 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" } %>
</div>

<div class="small-12 medium-3 column">
Expand All @@ -36,8 +36,10 @@
<% end %>
</div>

<%= 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" %>

<div id="investments">
<%= render '/admin/budget_investments/investments' %>
<%= render "investments" %>
</div>
1 change: 1 addition & 0 deletions app/views/admin/budget_investments/index.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$("#investments").html('<%= j render("admin/budget_investments/investments") %>');

0 comments on commit a1d83e4

Please sign in to comment.