Merge pull request #5498 from consuldemocracy/toggle_switch
Use a switch control to toggle selections
This commit is contained in:
@@ -80,9 +80,6 @@
|
|||||||
App.ColumnsSelector.toggleColumn(event);
|
App.ColumnsSelector.toggleColumn(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$(".column-selectable").on("inserted", function() {
|
|
||||||
App.ColumnsSelector.initColumns();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
$("#js-columns-selector-wrapper").children(":not(#column_selector_item_template)").remove();
|
$("#js-columns-selector-wrapper").children(":not(#column_selector_item_template)").remove();
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
.admin .admin-budget-investments {
|
||||||
|
td {
|
||||||
|
&[data-field=supports],
|
||||||
|
&[data-field=valuation_finished],
|
||||||
|
&[data-field=visible_to_valuators],
|
||||||
|
&[data-field=selected],
|
||||||
|
&[data-field=incompatible] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([data-field=id], [data-field=title], [data-field=supports]) {
|
||||||
|
font-size: $small-font-size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-switch [aria-pressed] {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
@include regular-button;
|
@include regular-button;
|
||||||
border-radius: $line-height;
|
border-radius: $line-height;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-width: rem-calc(100);
|
min-width: 6em;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<div id="investments" class="admin-budget-investments">
|
||||||
|
<%= link_to t("admin.budget_investments.index.download_current_selection"),
|
||||||
|
admin_budget_budget_investments_path(csv_params),
|
||||||
|
class: "float-right small clear" %>
|
||||||
|
|
||||||
|
<% if params[:advanced_filters].include?("winners") %>
|
||||||
|
<%= render Admin::Budgets::CalculateWinnersButtonComponent.new(budget, from_investments: true) %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if investments.any? %>
|
||||||
|
<h3 class="inline-block"><%= page_entries_info investments %></h3>
|
||||||
|
<%= render "admin/shared/columns_selector",
|
||||||
|
cookie: "investments-columns",
|
||||||
|
default: %w[id title supports admin valuator geozone feasibility price valuation_finished visible_to_valuators selected incompatible] %>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<%= render "filters_description", i18n_namespace: "admin.budget_investments.index" %>
|
||||||
|
|
||||||
|
<table class="table-for-mobile column-selectable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><%= link_to_investments_sorted_by :id %></th>
|
||||||
|
<th data-field="title"><%= link_to_investments_sorted_by :title %></th>
|
||||||
|
<th data-field="supports"><%= link_to_investments_sorted_by :supports %></th>
|
||||||
|
<th data-field="admin"><%= t("admin.budget_investments.index.list.admin") %></th>
|
||||||
|
<th data-field="author">
|
||||||
|
<%= t("admin.budget_investments.index.list.author") %>
|
||||||
|
</th>
|
||||||
|
<th data-field="valuator">
|
||||||
|
<%= t("admin.budget_investments.index.list.valuation_group") %> /
|
||||||
|
<%= t("admin.budget_investments.index.list.valuator") %>
|
||||||
|
</th>
|
||||||
|
<th data-field="geozone"><%= t("admin.budget_investments.index.list.geozone") %></th>
|
||||||
|
<th data-field="feasibility"><%= t("admin.budget_investments.index.list.feasibility") %></th>
|
||||||
|
<% if budget.show_money? %>
|
||||||
|
<th data-field="price"><%= t("admin.budget_investments.index.list.price") %></th>
|
||||||
|
<% end %>
|
||||||
|
<th data-field="valuation_finished">
|
||||||
|
<%= t("admin.budget_investments.index.list.valuation_finished") %>
|
||||||
|
</th>
|
||||||
|
<th data-field="visible_to_valuators">
|
||||||
|
<%= t("admin.budget_investments.index.list.visible_to_valuators") %>
|
||||||
|
</th>
|
||||||
|
<th data-field="selected"><%= t("admin.budget_investments.index.list.selected") %></th>
|
||||||
|
<% if params[:advanced_filters]&.include?("selected") %>
|
||||||
|
<th data-field="incompatible"><%= t("admin.budget_investments.index.list.incompatible") %></th>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<% investments.each do |investment| %>
|
||||||
|
<%= render Admin::BudgetInvestments::RowComponent.new(investment) %>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= paginate investments %>
|
||||||
|
<% else %>
|
||||||
|
<div class="callout primary clear">
|
||||||
|
<%= t("admin.budget_investments.index.no_budget_investments") %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
class Admin::BudgetInvestments::InvestmentsComponent < ApplicationComponent
|
||||||
|
attr_reader :budget, :investments
|
||||||
|
use_helpers :set_direction, :set_sorting_icon
|
||||||
|
|
||||||
|
def initialize(budget, investments)
|
||||||
|
@budget = budget
|
||||||
|
@investments = investments
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def csv_params
|
||||||
|
csv_params = params.clone.merge(format: :csv)
|
||||||
|
csv_params = csv_params.to_unsafe_h.transform_keys(&:to_sym)
|
||||||
|
csv_params.delete(:page)
|
||||||
|
csv_params
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_investments_sorted_by(column)
|
||||||
|
direction = set_direction(params[:direction])
|
||||||
|
icon = set_sorting_icon(direction, column)
|
||||||
|
|
||||||
|
translation = t("admin.budget_investments.index.list.#{column}")
|
||||||
|
|
||||||
|
link_to(
|
||||||
|
safe_join([translation, tag.span(class: "icon-sortable #{icon}")]),
|
||||||
|
admin_budget_budget_investments_path(sort_by: column, direction: direction)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<tr id="<%= dom_id(investment) %>" class="budget_investment">
|
||||||
|
<td class="text-right" data-field="id">
|
||||||
|
<strong><%= investment.id %></strong>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="title">
|
||||||
|
<%= link_to investment.title, investment_path, target: "_blank" %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="supports">
|
||||||
|
<%= investment.total_votes %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="admin">
|
||||||
|
<%= administrator_info %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="author">
|
||||||
|
<%= investment.author.name %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="valuator">
|
||||||
|
<%= valuators_info %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="geozone">
|
||||||
|
<%= investment.heading.name %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="feasibility">
|
||||||
|
<%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}") %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<% if budget.show_money? %>
|
||||||
|
<td data-field="price">
|
||||||
|
<%= investment.formatted_price %>
|
||||||
|
</td>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<td data-field="valuation_finished">
|
||||||
|
<%= investment.valuation_finished? ? t("shared.yes") : t("shared.no") %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="visible_to_valuators">
|
||||||
|
<%= render Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent.new(investment) %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td data-field="selected">
|
||||||
|
<%= render Admin::BudgetInvestments::ToggleSelectionComponent.new(investment) %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<% if params[:advanced_filters]&.include?("selected") %>
|
||||||
|
<td data-field="incompatible">
|
||||||
|
<%= investment.incompatible? ? t("shared.yes") : t("shared.no") %>
|
||||||
|
</td>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
38
app/components/admin/budget_investments/row_component.rb
Normal file
38
app/components/admin/budget_investments/row_component.rb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
class Admin::BudgetInvestments::RowComponent < ApplicationComponent
|
||||||
|
attr_reader :investment
|
||||||
|
|
||||||
|
def initialize(investment)
|
||||||
|
@investment = investment
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def budget
|
||||||
|
investment.budget
|
||||||
|
end
|
||||||
|
|
||||||
|
def investment_path
|
||||||
|
admin_budget_budget_investment_path(budget_id: budget.id,
|
||||||
|
id: investment.id,
|
||||||
|
params: Budget::Investment.filter_params(params).to_h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def administrator_info
|
||||||
|
if investment.administrator.present?
|
||||||
|
tag.span(investment.administrator.description_or_name,
|
||||||
|
title: t("admin.budget_investments.index.assigned_admin"))
|
||||||
|
else
|
||||||
|
t("admin.budget_investments.index.no_admin_assigned")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def valuators_info
|
||||||
|
valuators = [investment.assigned_valuation_groups, investment.assigned_valuators].compact
|
||||||
|
|
||||||
|
if valuators.present?
|
||||||
|
valuators.join(", ")
|
||||||
|
else
|
||||||
|
t("admin.budget_investments.index.no_valuators_assigned")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<% if can?(action, investment) %>
|
||||||
|
<%= render Admin::ToggleSwitchComponent.new(action, investment, pressed: selected?, **options) %>
|
||||||
|
<% elsif selected? %>
|
||||||
|
<%= selected_text %>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
class Admin::BudgetInvestments::ToggleSelectionComponent < ApplicationComponent
|
||||||
|
attr_reader :investment
|
||||||
|
use_helpers :can?
|
||||||
|
delegate :selected?, to: :investment
|
||||||
|
|
||||||
|
def initialize(investment)
|
||||||
|
@investment = investment
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def selected_text
|
||||||
|
t("admin.budget_investments.index.selected")
|
||||||
|
end
|
||||||
|
|
||||||
|
def action
|
||||||
|
if selected?
|
||||||
|
:deselect
|
||||||
|
else
|
||||||
|
:select
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def path
|
||||||
|
url_for({
|
||||||
|
controller: "admin/budget_investments",
|
||||||
|
action: action,
|
||||||
|
budget_id: investment.budget,
|
||||||
|
id: investment,
|
||||||
|
filter: params[:filter],
|
||||||
|
sort_by: params[:sort_by],
|
||||||
|
min_total_supports: params[:min_total_supports],
|
||||||
|
max_total_supports: params[:max_total_supports],
|
||||||
|
advanced_filters: params[:advanced_filters],
|
||||||
|
page: params[:page]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def options
|
||||||
|
{
|
||||||
|
"aria-label": label,
|
||||||
|
form_class: "toggle-selection",
|
||||||
|
path: path
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def label
|
||||||
|
t("admin.actions.label", action: t("admin.actions.select"), name: investment.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<% if can?(:admin_update, investment) %>
|
||||||
|
<%= render Admin::ToggleSwitchComponent.new(action, investment, pressed: visible_to_valuators?, **options) %>
|
||||||
|
<% else %>
|
||||||
|
<%= text %>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
class Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent < ApplicationComponent
|
||||||
|
attr_reader :investment
|
||||||
|
use_helpers :can?
|
||||||
|
delegate :visible_to_valuators?, to: :investment
|
||||||
|
|
||||||
|
def initialize(investment)
|
||||||
|
@investment = investment
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def action
|
||||||
|
if visible_to_valuators?
|
||||||
|
:hide_from_valuators
|
||||||
|
else
|
||||||
|
:show_to_valuators
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def text
|
||||||
|
if visible_to_valuators?
|
||||||
|
t("shared.yes")
|
||||||
|
else
|
||||||
|
t("shared.no")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def options
|
||||||
|
{
|
||||||
|
"aria-label": label,
|
||||||
|
form_class: "visible-to-valuators"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def label
|
||||||
|
t("admin.actions.show_to_valuators", name: investment.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<%= render Admin::ToggleSwitchComponent.new(action, proposal, pressed: selected?, **options) %>
|
||||||
31
app/components/admin/proposals/toggle_selection_component.rb
Normal file
31
app/components/admin/proposals/toggle_selection_component.rb
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
class Admin::Proposals::ToggleSelectionComponent < ApplicationComponent
|
||||||
|
attr_reader :proposal
|
||||||
|
|
||||||
|
def initialize(proposal)
|
||||||
|
@proposal = proposal
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def action
|
||||||
|
if selected?
|
||||||
|
:deselect
|
||||||
|
else
|
||||||
|
:select
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def selected?
|
||||||
|
proposal.selected?
|
||||||
|
end
|
||||||
|
|
||||||
|
def options
|
||||||
|
{
|
||||||
|
"aria-label": label
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def label
|
||||||
|
t("admin.actions.label", action: t("admin.actions.select"), name: proposal.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1 +1 @@
|
|||||||
<%= render Admin::ActionComponent.new(action, record, **default_options.merge(options)) %>
|
<%= render Admin::ActionComponent.new(action, record, **html_options) %>
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ class Admin::ToggleSwitchComponent < ApplicationComponent
|
|||||||
method: :patch,
|
method: :patch,
|
||||||
remote: true,
|
remote: true,
|
||||||
"aria-pressed": pressed?,
|
"aria-pressed": pressed?,
|
||||||
form_class: "toggle-switch"
|
form_class: "toggle-switch #{options[:form_class]}".strip
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def html_options
|
||||||
|
default_options.merge(options.except(:form_class))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,19 +6,18 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
|||||||
feature_flag :budgets
|
feature_flag :budgets
|
||||||
|
|
||||||
has_orders %w[oldest], only: [:show, :edit]
|
has_orders %w[oldest], only: [:show, :edit]
|
||||||
has_filters %w[all], only: [:index, :toggle_selection]
|
has_filters %w[all], only: :index
|
||||||
|
|
||||||
before_action :load_budget
|
before_action :load_budget
|
||||||
before_action :load_investment, only: [:show, :edit, :update, :toggle_selection]
|
before_action :load_investment, except: [:index]
|
||||||
before_action :load_ballot, only: [:show, :index]
|
before_action :load_ballot, only: [:show, :index]
|
||||||
before_action :parse_valuation_filters
|
before_action :parse_valuation_filters
|
||||||
before_action :load_investments, only: [:index, :toggle_selection]
|
before_action :load_investments, only: :index
|
||||||
|
|
||||||
def index
|
def index
|
||||||
load_tags
|
load_tags
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.js
|
|
||||||
format.csv do
|
format.csv do
|
||||||
send_data Budget::Investment::Exporter.new(@investments).to_csv,
|
send_data Budget::Investment::Exporter.new(@investments).to_csv,
|
||||||
filename: "budget_investments.csv"
|
filename: "budget_investments.csv"
|
||||||
@@ -40,8 +39,6 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
|||||||
def update
|
def update
|
||||||
authorize! :admin_update, @investment
|
authorize! :admin_update, @investment
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.html do
|
|
||||||
if @investment.update(budget_investment_params)
|
if @investment.update(budget_investment_params)
|
||||||
redirect_to admin_budget_budget_investment_path(@budget,
|
redirect_to admin_budget_budget_investment_path(@budget,
|
||||||
@investment,
|
@investment,
|
||||||
@@ -55,17 +52,44 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
def show_to_valuators
|
||||||
@investment.update!(budget_investment_params)
|
authorize! :admin_update, @investment
|
||||||
end
|
@investment.update!(visible_to_valuators: true)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.budget_investment") }
|
||||||
|
format.js { render :toggle_visible_to_valuators }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def toggle_selection
|
def hide_from_valuators
|
||||||
authorize! :toggle_selection, @investment
|
authorize! :admin_update, @investment
|
||||||
@investment.toggle :selected
|
@investment.update!(visible_to_valuators: false)
|
||||||
@investment.save!
|
|
||||||
load_investments
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.budget_investment") }
|
||||||
|
format.js { render :toggle_visible_to_valuators }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def select
|
||||||
|
authorize! :select, @investment
|
||||||
|
@investment.update!(selected: true)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.budget_investment") }
|
||||||
|
format.js { render :toggle_selection }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deselect
|
||||||
|
authorize! :deselect, @investment
|
||||||
|
@investment.update!(selected: false)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.budget_investment") }
|
||||||
|
format.js { render :toggle_selection }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -96,7 +120,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
|||||||
|
|
||||||
def allowed_params
|
def allowed_params
|
||||||
attributes = [:external_url, :heading_id, :administrator_id, :tag_list,
|
attributes = [:external_url, :heading_id, :administrator_id, :tag_list,
|
||||||
:valuation_tag_list, :incompatible, :visible_to_valuators, :selected,
|
:valuation_tag_list, :incompatible, :selected,
|
||||||
:milestone_tag_list, valuator_ids: [], valuator_group_ids: []]
|
:milestone_tag_list, valuator_ids: [], valuator_group_ids: []]
|
||||||
[*attributes, translation_params(Budget::Investment)]
|
[*attributes, translation_params(Budget::Investment)]
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,8 +8,21 @@ class Admin::Legislation::ProposalsController < Admin::Legislation::BaseControll
|
|||||||
@proposals = @proposals.send("sort_by_#{@current_order}").page(params[:page])
|
@proposals = @proposals.send("sort_by_#{@current_order}").page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def toggle_selection
|
def select
|
||||||
@proposal.toggle :selected
|
@proposal.update!(selected: true)
|
||||||
@proposal.save!
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.proposal") }
|
||||||
|
format.js { render :toggle_selection }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deselect
|
||||||
|
@proposal.update!(selected: false)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.proposal") }
|
||||||
|
format.js { render :toggle_selection }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,9 +19,22 @@ class Admin::ProposalsController < Admin::BaseController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def toggle_selection
|
def select
|
||||||
@proposal.toggle :selected
|
@proposal.update!(selected: true)
|
||||||
@proposal.save!
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.proposal") }
|
||||||
|
format.js { render :toggle_selection }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def deselect
|
||||||
|
@proposal.update!(selected: false)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to request.referer, notice: t("flash.actions.update.proposal") }
|
||||||
|
format.js { render :toggle_selection }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -3,18 +3,6 @@ module BudgetInvestmentsHelper
|
|||||||
params.map { |af| t("admin.budget_investments.index.filters.#{af}") }.join(", ")
|
params.map { |af| t("admin.budget_investments.index.filters.#{af}") }.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_investments_sorted_by(column)
|
|
||||||
direction = set_direction(params[:direction])
|
|
||||||
icon = set_sorting_icon(direction, column)
|
|
||||||
|
|
||||||
translation = t("admin.budget_investments.index.list.#{column}")
|
|
||||||
|
|
||||||
link_to(
|
|
||||||
safe_join([translation, tag.span(class: "icon-sortable #{icon}")]),
|
|
||||||
admin_budget_budget_investments_path(sort_by: column, direction: direction)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_sorting_icon(direction, sort_by)
|
def set_sorting_icon(direction, sort_by)
|
||||||
if sort_by.to_s == params[:sort_by]
|
if sort_by.to_s == params[:sort_by]
|
||||||
if direction == "desc"
|
if direction == "desc"
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
module BudgetsHelper
|
module BudgetsHelper
|
||||||
def csv_params
|
|
||||||
csv_params = params.clone.merge(format: :csv)
|
|
||||||
csv_params = csv_params.to_unsafe_h.transform_keys(&:to_sym)
|
|
||||||
csv_params.delete(:page)
|
|
||||||
csv_params
|
|
||||||
end
|
|
||||||
|
|
||||||
def namespaced_budget_investment_path(investment, options = {})
|
def namespaced_budget_investment_path(investment, options = {})
|
||||||
case namespace
|
case namespace
|
||||||
when "management"
|
when "management"
|
||||||
|
|||||||
@@ -64,25 +64,6 @@ module ProposalsHelper
|
|||||||
proposals_current_view == "default" ? "minimal" : "default"
|
proposals_current_view == "default" ? "minimal" : "default"
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_toggle_proposal_selection(proposal)
|
|
||||||
if proposal.selected?
|
|
||||||
button_text = t("admin.proposals.index.selected")
|
|
||||||
html_class = "button expanded"
|
|
||||||
else
|
|
||||||
button_text = t("admin.proposals.index.select")
|
|
||||||
html_class = "button hollow expanded"
|
|
||||||
end
|
|
||||||
|
|
||||||
case proposal.class.to_s
|
|
||||||
when "Proposal"
|
|
||||||
path = toggle_selection_admin_proposal_path(proposal)
|
|
||||||
when "Legislation::Proposal"
|
|
||||||
path = toggle_selection_admin_legislation_process_proposal_path(proposal.process, proposal)
|
|
||||||
end
|
|
||||||
|
|
||||||
link_to button_text, path, remote: true, method: :patch, class: html_class
|
|
||||||
end
|
|
||||||
|
|
||||||
def css_for_proposal_info_row(proposal)
|
def css_for_proposal_info_row(proposal)
|
||||||
if proposal.image.present?
|
if proposal.image.present?
|
||||||
if params[:selected].present?
|
if params[:selected].present?
|
||||||
|
|||||||
@@ -71,10 +71,13 @@ module Abilities
|
|||||||
|
|
||||||
can [:read, :create, :update, :destroy], Budget::Group
|
can [:read, :create, :update, :destroy], Budget::Group
|
||||||
can [:read, :create, :update, :destroy], Budget::Heading
|
can [:read, :create, :update, :destroy], Budget::Heading
|
||||||
can [:hide, :admin_update, :toggle_selection], Budget::Investment
|
can [:hide, :admin_update], Budget::Investment
|
||||||
can [:valuate, :comment_valuation], Budget::Investment
|
can [:valuate, :comment_valuation], Budget::Investment
|
||||||
cannot [:admin_update, :toggle_selection, :valuate, :comment_valuation],
|
cannot [:admin_update, :valuate, :comment_valuation],
|
||||||
Budget::Investment, budget: { phase: "finished" }
|
Budget::Investment, budget: { phase: "finished" }
|
||||||
|
can [:select, :deselect], Budget::Investment do |investment|
|
||||||
|
investment.feasible? && investment.valuation_finished? && !investment.budget.finished?
|
||||||
|
end
|
||||||
|
|
||||||
can :create, Budget::ValuatorAssignment
|
can :create, Budget::ValuatorAssignment
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
<%= link_to t("admin.budget_investments.index.download_current_selection"),
|
|
||||||
admin_budget_budget_investments_path(csv_params),
|
|
||||||
class: "float-right small clear" %>
|
|
||||||
|
|
||||||
<% if params[:advanced_filters].include?("winners") %>
|
|
||||||
<%= render Admin::Budgets::CalculateWinnersButtonComponent.new(@budget, from_investments: true) %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if @investments.any? %>
|
|
||||||
<h3 class="inline-block"><%= page_entries_info @investments %></h3>
|
|
||||||
<%= render "admin/shared/columns_selector",
|
|
||||||
cookie: "investments-columns",
|
|
||||||
default: %w[id title supports admin valuator geozone feasibility price valuation_finished visible_to_valuators selected incompatible] %>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<%= render "filters_description", i18n_namespace: "admin.budget_investments.index" %>
|
|
||||||
|
|
||||||
<table class="table-for-mobile column-selectable">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><%= link_to_investments_sorted_by :id %></th>
|
|
||||||
<th data-field="title"><%= link_to_investments_sorted_by :title %></th>
|
|
||||||
<th data-field="supports"><%= link_to_investments_sorted_by :supports %></th>
|
|
||||||
<th data-field="admin"><%= t("admin.budget_investments.index.list.admin") %></th>
|
|
||||||
<th data-field="author">
|
|
||||||
<%= t("admin.budget_investments.index.list.author") %>
|
|
||||||
</th>
|
|
||||||
<th data-field="valuator">
|
|
||||||
<%= t("admin.budget_investments.index.list.valuation_group") %> /
|
|
||||||
<%= t("admin.budget_investments.index.list.valuator") %>
|
|
||||||
</th>
|
|
||||||
<th data-field="geozone"><%= t("admin.budget_investments.index.list.geozone") %></th>
|
|
||||||
<th data-field="feasibility"><%= t("admin.budget_investments.index.list.feasibility") %></th>
|
|
||||||
<% if @budget.show_money? %>
|
|
||||||
<th data-field="price"><%= t("admin.budget_investments.index.list.price") %></th>
|
|
||||||
<% end %>
|
|
||||||
<th data-field="valuation_finished">
|
|
||||||
<%= t("admin.budget_investments.index.list.valuation_finished") %>
|
|
||||||
</th>
|
|
||||||
<th data-field="visible_to_valuators">
|
|
||||||
<%= t("admin.budget_investments.index.list.visible_to_valuators") %>
|
|
||||||
</th>
|
|
||||||
<th data-field="selected"><%= t("admin.budget_investments.index.list.selected") %></th>
|
|
||||||
<% if params[:advanced_filters]&.include?("selected") %>
|
|
||||||
<th data-field="incompatible"><%= t("admin.budget_investments.index.list.incompatible") %></th>
|
|
||||||
<% end %>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
<% @investments.each do |investment| %>
|
|
||||||
<tr id="<%= dom_id(investment) %>" class="budget_investment">
|
|
||||||
<%= render "/admin/budget_investments/select_investment", investment: investment %>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<%= paginate @investments %>
|
|
||||||
<% else %>
|
|
||||||
<div class="callout primary clear">
|
|
||||||
<%= t("admin.budget_investments.index.no_budget_investments") %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
<td class="text-right" data-field="id">
|
|
||||||
<strong><%= investment.id %></strong>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td data-field="title">
|
|
||||||
<%= link_to investment.title,
|
|
||||||
admin_budget_budget_investment_path(budget_id: @budget.id,
|
|
||||||
id: investment.id,
|
|
||||||
params: Budget::Investment.filter_params(params).to_h),
|
|
||||||
target: "_blank" %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-center" data-field="supports">
|
|
||||||
<%= investment.total_votes %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="small" data-field="admin">
|
|
||||||
<% if investment.administrator.present? %>
|
|
||||||
<span title="<%= t("admin.budget_investments.index.assigned_admin") %>">
|
|
||||||
<%= investment.administrator.description_or_name %>
|
|
||||||
</span>
|
|
||||||
<% else %>
|
|
||||||
<%= t("admin.budget_investments.index.no_admin_assigned") %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="small" data-field="author">
|
|
||||||
<%= investment.author.name %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="small" data-field="valuator">
|
|
||||||
<% valuators = [investment.assigned_valuation_groups, investment.assigned_valuators].compact %>
|
|
||||||
<% no_valuators_assigned = t("admin.budget_investments.index.no_valuators_assigned") %>
|
|
||||||
<%= valuators.present? ? valuators.join(", ") : no_valuators_assigned %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="small" data-field="geozone">
|
|
||||||
<%= investment.heading.name %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="small" data-field="feasibility">
|
|
||||||
<%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}") %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<% if @budget.show_money? %>
|
|
||||||
<td class="small" data-field="price">
|
|
||||||
<%= investment.formatted_price %>
|
|
||||||
</td>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<td class="small text-center" data-field="valuation_finished">
|
|
||||||
<%= investment.valuation_finished? ? t("shared.yes") : t("shared.no") %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="small text-center" data-field="visible_to_valuators">
|
|
||||||
<% if can?(:admin_update, investment) %>
|
|
||||||
<%= form_for [:admin, investment.budget, investment], remote: true, format: :json do |f| %>
|
|
||||||
<%= f.check_box :visible_to_valuators,
|
|
||||||
label: false,
|
|
||||||
class: "js-submit-on-change",
|
|
||||||
id: "budget_investment_visible_to_valuators" %>
|
|
||||||
<% end %>
|
|
||||||
<% else %>
|
|
||||||
<%= investment.visible_to_valuators? ? t("shared.yes") : t("shared.no") %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td id="selection" class="small text-center" data-field="selected">
|
|
||||||
<% if investment.selected? %>
|
|
||||||
<%= link_to_if can?(:toggle_selection, investment),
|
|
||||||
t("admin.budget_investments.index.selected"),
|
|
||||||
toggle_selection_admin_budget_budget_investment_path(
|
|
||||||
@budget,
|
|
||||||
investment,
|
|
||||||
filter: params[:filter],
|
|
||||||
sort_by: params[:sort_by],
|
|
||||||
min_total_supports: params[:min_total_supports],
|
|
||||||
max_total_supports: params[:max_total_supports],
|
|
||||||
advanced_filters: params[:advanced_filters],
|
|
||||||
page: params[:page]
|
|
||||||
),
|
|
||||||
method: :patch,
|
|
||||||
remote: true,
|
|
||||||
class: "button small expanded" %>
|
|
||||||
<% elsif investment.feasible? && investment.valuation_finished? %>
|
|
||||||
<% if can?(:toggle_selection, investment) %>
|
|
||||||
<%= link_to t("admin.budget_investments.index.select"),
|
|
||||||
toggle_selection_admin_budget_budget_investment_path(
|
|
||||||
@budget,
|
|
||||||
investment,
|
|
||||||
filter: params[:filter],
|
|
||||||
sort_by: params[:sort_by],
|
|
||||||
min_total_supports: params[:min_total_supports],
|
|
||||||
max_total_supports: params[:max_total_supports],
|
|
||||||
advanced_filters: params[:advanced_filters],
|
|
||||||
page: params[:page]
|
|
||||||
),
|
|
||||||
method: :patch,
|
|
||||||
remote: true,
|
|
||||||
class: "button small hollow expanded" %>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<% if params[:advanced_filters]&.include?("selected") %>
|
|
||||||
<td class="small text-center" data-field="incompatible">
|
|
||||||
<%= investment.incompatible? ? t("shared.yes") : t("shared.no") %>
|
|
||||||
</td>
|
|
||||||
<% end %>
|
|
||||||
@@ -12,6 +12,4 @@
|
|||||||
|
|
||||||
<%= render "/shared/filter_subnav", i18n_namespace: "admin.budget_investments.index" %>
|
<%= render "/shared/filter_subnav", i18n_namespace: "admin.budget_investments.index" %>
|
||||||
|
|
||||||
<div id="investments">
|
<%= render Admin::BudgetInvestments::InvestmentsComponent.new(@budget, @investments) %>
|
||||||
<%= render "investments" %>
|
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
$("#investments").html("<%= j render("admin/budget_investments/investments") %>");
|
|
||||||
@@ -1 +1,4 @@
|
|||||||
$("#<%= dom_id(@investment) %>").html("<%= j render("select_investment", investment: @investment) %>").trigger("inserted");
|
<%= render "admin/shared/toggle_switch",
|
||||||
|
record: @investment,
|
||||||
|
form_class: "toggle-selection",
|
||||||
|
new_content: render(Admin::BudgetInvestments::ToggleSelectionComponent.new(@investment)) %>
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<%= render "admin/shared/toggle_switch",
|
||||||
|
record: @investment,
|
||||||
|
form_class: "visible-to-valuators",
|
||||||
|
new_content: render(Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent.new(@investment)) %>
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
var replacement = $("<%= j render Admin::BudgetPhases::ToggleEnabledComponent.new(@phase) %>");
|
<%= render "admin/shared/toggle_switch",
|
||||||
var form = $("#<%= dom_id(@phase) %> .toggle-switch");
|
record: @phase,
|
||||||
|
new_content: render(Admin::BudgetPhases::ToggleEnabledComponent.new(@phase)) %>
|
||||||
form.replaceWith(replacement);
|
|
||||||
replacement.find("[type='submit']").focus();
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<td class="text-center"><%= proposal.id %></td>
|
<td class="text-center"><%= proposal.id %></td>
|
||||||
<td><%= proposal.title %></td>
|
<td><%= proposal.title %></td>
|
||||||
<td class="text-center"><%= proposal.votes_score %></td>
|
<td class="text-center"><%= proposal.votes_score %></td>
|
||||||
<td class="select"><%= render "select_proposal", proposal: proposal %></td>
|
<td><%= render Admin::Proposals::ToggleSelectionComponent.new(proposal) %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<%= link_to_toggle_proposal_selection(proposal) %>
|
|
||||||
@@ -1 +1,3 @@
|
|||||||
$("#<%= dom_id(@proposal) %> .select").html("<%= j render("select_proposal", proposal: @proposal) %>");
|
<%= render "admin/shared/toggle_switch",
|
||||||
|
record: @proposal,
|
||||||
|
new_content: render(Admin::Proposals::ToggleSelectionComponent.new(@proposal)) %>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<%= link_to_toggle_proposal_selection(proposal) %>
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<td><%= link_to proposal.title, admin_proposal_path(proposal) %></td>
|
<td><%= link_to proposal.title, admin_proposal_path(proposal) %></td>
|
||||||
<td><%= proposal.author.username %></td>
|
<td><%= proposal.author.username %></td>
|
||||||
<td><%= proposal.milestones.count %></td>
|
<td><%= proposal.milestones.count %></td>
|
||||||
<td class="js-select"><%= render "select_proposal", proposal: proposal %></td>
|
<td><%= render Admin::Proposals::ToggleSelectionComponent.new(proposal) %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
$("#<%= dom_id(@proposal) %> .js-select").html("<%= j render("select_proposal", proposal: @proposal) %>");
|
<%= render "admin/shared/toggle_switch",
|
||||||
|
record: @proposal,
|
||||||
|
new_content: render(Admin::Proposals::ToggleSelectionComponent.new(@proposal)) %>
|
||||||
|
|||||||
5
app/views/admin/shared/_toggle_switch.js.erb
Normal file
5
app/views/admin/shared/_toggle_switch.js.erb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
var new_toggle_switch = $("<%= j new_content %>");
|
||||||
|
var current_toggle_switch = $("#<%= dom_id(record) %> .<%= local_assigns[:form_class] || "toggle-switch" %>");
|
||||||
|
|
||||||
|
current_toggle_switch.replaceWith(new_toggle_switch);
|
||||||
|
new_toggle_switch.find("[type='submit']").focus();
|
||||||
@@ -24,7 +24,7 @@ module ActionDispatch::Routing::UrlFor
|
|||||||
end
|
end
|
||||||
|
|
||||||
def namespaced_polymorphic_path(namespace, resource, options = {})
|
def namespaced_polymorphic_path(namespace, resource, options = {})
|
||||||
if %w[Budget::Group Budget::Heading Legislation::DraftVersion Legislation::Question
|
if %w[Budget::Group Budget::Heading Legislation::DraftVersion Legislation::Proposal Legislation::Question
|
||||||
Poll::Booth Poll::BoothAssignment Poll::Officer Poll::Question Poll::Question::Option
|
Poll::Booth Poll::BoothAssignment Poll::Officer Poll::Question Poll::Question::Option
|
||||||
Poll::Question::Option::Video Poll::Shift SDG::LocalTarget].include?(resource.class.name)
|
Poll::Question::Option::Video Poll::Shift SDG::LocalTarget].include?(resource.class.name)
|
||||||
resolve = resolve_for(resource)
|
resolve = resolve_for(resource)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ en:
|
|||||||
unmark_featured: Unmark featured
|
unmark_featured: Unmark featured
|
||||||
edit: Edit
|
edit: Edit
|
||||||
configure: Configure
|
configure: Configure
|
||||||
|
select: Select
|
||||||
|
show_to_valuators: "Show %{name} to valuators"
|
||||||
officing_booth:
|
officing_booth:
|
||||||
title: "You are officing the booth located at %{booth}. If this is not correct, do not continue and call the help phone number. Thank you."
|
title: "You are officing the booth located at %{booth}. If this is not correct, do not continue and call the help phone number. Thank you."
|
||||||
banners:
|
banners:
|
||||||
@@ -268,7 +270,6 @@ en:
|
|||||||
unfeasible: "Unfeasible"
|
unfeasible: "Unfeasible"
|
||||||
undecided: "Undecided"
|
undecided: "Undecided"
|
||||||
selected: "Selected"
|
selected: "Selected"
|
||||||
select: "Select"
|
|
||||||
list:
|
list:
|
||||||
id: ID
|
id: ID
|
||||||
title: Title
|
title: Title
|
||||||
@@ -1294,7 +1295,6 @@ en:
|
|||||||
title: Proposals
|
title: Proposals
|
||||||
id: ID
|
id: ID
|
||||||
author: Author
|
author: Author
|
||||||
select: Select
|
|
||||||
selected: Selected
|
selected: Selected
|
||||||
milestones: Milestones
|
milestones: Milestones
|
||||||
no_proposals: There are no proposals.
|
no_proposals: There are no proposals.
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ es:
|
|||||||
unmark_featured: Quitar destacado
|
unmark_featured: Quitar destacado
|
||||||
edit: Editar
|
edit: Editar
|
||||||
configure: Configurar
|
configure: Configurar
|
||||||
|
select: Seleccionar
|
||||||
|
show_to_valuators: "Mostrar %{name} a evaluadores"
|
||||||
officing_booth:
|
officing_booth:
|
||||||
title: "Estás ahora mismo en la mesa ubicada en %{booth}. Si esto no es correcto no sigas adelante y llama al teléfono de incidencias. Gracias."
|
title: "Estás ahora mismo en la mesa ubicada en %{booth}. Si esto no es correcto no sigas adelante y llama al teléfono de incidencias. Gracias."
|
||||||
banners:
|
banners:
|
||||||
@@ -268,7 +270,6 @@ es:
|
|||||||
unfeasible: "Inviable"
|
unfeasible: "Inviable"
|
||||||
undecided: "Sin decidir"
|
undecided: "Sin decidir"
|
||||||
selected: "Seleccionado"
|
selected: "Seleccionado"
|
||||||
select: "Seleccionar"
|
|
||||||
list:
|
list:
|
||||||
id: ID
|
id: ID
|
||||||
title: Título
|
title: Título
|
||||||
@@ -1295,7 +1296,6 @@ es:
|
|||||||
id: ID
|
id: ID
|
||||||
author: Autor
|
author: Autor
|
||||||
milestones: Hitos
|
milestones: Hitos
|
||||||
select: Seleccionar
|
|
||||||
selected: Seleccionada
|
selected: Seleccionada
|
||||||
no_proposals: No hay propuestas.
|
no_proposals: No hay propuestas.
|
||||||
show:
|
show:
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ namespace :admin do
|
|||||||
resources :debates, only: [:index, :show]
|
resources :debates, only: [:index, :show]
|
||||||
|
|
||||||
resources :proposals, only: [:index, :show, :update] do
|
resources :proposals, only: [:index, :show, :update] do
|
||||||
member { patch :toggle_selection }
|
member do
|
||||||
|
patch :select
|
||||||
|
patch :deselect
|
||||||
|
end
|
||||||
|
|
||||||
resources :milestones, controller: "proposal_milestones"
|
resources :milestones, controller: "proposal_milestones"
|
||||||
resources :progress_bars, except: :show, controller: "proposal_progress_bars"
|
resources :progress_bars, except: :show, controller: "proposal_progress_bars"
|
||||||
end
|
end
|
||||||
@@ -62,7 +66,12 @@ namespace :admin do
|
|||||||
end
|
end
|
||||||
|
|
||||||
resources :budget_investments, only: [:index, :show, :edit, :update] do
|
resources :budget_investments, only: [:index, :show, :edit, :update] do
|
||||||
member { patch :toggle_selection }
|
member do
|
||||||
|
patch :select
|
||||||
|
patch :deselect
|
||||||
|
patch :show_to_valuators
|
||||||
|
patch :hide_from_valuators
|
||||||
|
end
|
||||||
|
|
||||||
resources :audits, only: :show, controller: "budget_investment_audits"
|
resources :audits, only: :show, controller: "budget_investment_audits"
|
||||||
resources :milestones, controller: "budget_investment_milestones"
|
resources :milestones, controller: "budget_investment_milestones"
|
||||||
@@ -232,7 +241,10 @@ namespace :admin do
|
|||||||
resources :processes do
|
resources :processes do
|
||||||
resources :questions
|
resources :questions
|
||||||
resources :proposals do
|
resources :proposals do
|
||||||
member { patch :toggle_selection }
|
member do
|
||||||
|
patch :select
|
||||||
|
patch :deselect
|
||||||
|
end
|
||||||
end
|
end
|
||||||
resources :draft_versions
|
resources :draft_versions
|
||||||
resources :milestones
|
resources :milestones
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::BudgetInvestments::ToggleSelectionComponent, :admin do
|
||||||
|
context "open budget" do
|
||||||
|
let(:budget) { create(:budget) }
|
||||||
|
|
||||||
|
it "is not rendered for not-yet-evaluated investments" do
|
||||||
|
unfeasible_investment = create(:budget_investment, :unfeasible, budget: budget)
|
||||||
|
feasible_investment = create(:budget_investment, :feasible, budget: budget)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(unfeasible_investment)
|
||||||
|
expect(page).not_to be_rendered
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(feasible_investment)
|
||||||
|
expect(page).not_to be_rendered
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders a button to select unselected evaluated investments" do
|
||||||
|
valuation_finished_investment = create(:budget_investment, :feasible, :finished, budget: budget)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(valuation_finished_investment)
|
||||||
|
|
||||||
|
expect(page).to have_button count: 1
|
||||||
|
expect(page).to have_button exact_text: "No"
|
||||||
|
expect(page).to have_css "button[aria-pressed='false']"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders a button to deselect selected investments" do
|
||||||
|
selected_investment = create(:budget_investment, :selected, budget: budget)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(selected_investment)
|
||||||
|
|
||||||
|
expect(page).to have_button count: 1
|
||||||
|
expect(page).to have_button exact_text: "Yes"
|
||||||
|
expect(page).to have_css "button[aria-pressed='true']"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "finished budget" do
|
||||||
|
let(:budget) { create(:budget, :finished) }
|
||||||
|
|
||||||
|
it "is not rendered for unselected investments" do
|
||||||
|
unfeasible_investment = create(:budget_investment, :unfeasible, budget: budget)
|
||||||
|
feasible_investment = create(:budget_investment, :feasible, budget: budget)
|
||||||
|
valuation_finished_investment = create(:budget_investment, :feasible, :finished, budget: budget)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(unfeasible_investment)
|
||||||
|
expect(page).not_to be_rendered
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(feasible_investment)
|
||||||
|
expect(page).not_to be_rendered
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(valuation_finished_investment)
|
||||||
|
expect(page).not_to be_rendered
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders plain text for selected investments" do
|
||||||
|
selected_investment = create(:budget_investment, :selected, budget: budget)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleSelectionComponent.new(selected_investment)
|
||||||
|
|
||||||
|
expect(page).to have_content "Selected"
|
||||||
|
expect(page).not_to have_button
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent, :admin do
|
||||||
|
describe "aria-pressed attribute" do
|
||||||
|
it "is true for investments visible to valuators" do
|
||||||
|
investment = create(:budget_investment, :visible_to_valuators)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent.new(investment)
|
||||||
|
|
||||||
|
expect(page).to have_css "[aria-pressed=true]"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is true for investments invisible to valuators" do
|
||||||
|
investment = create(:budget_investment, :invisible_to_valuators)
|
||||||
|
|
||||||
|
render_inline Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent.new(investment)
|
||||||
|
|
||||||
|
expect(page).to have_css "[aria-pressed=false]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::Proposals::ToggleSelectionComponent, :admin do
|
||||||
|
describe "aria-pressed attribute" do
|
||||||
|
it "is true for selected proposals" do
|
||||||
|
proposal = create(:proposal, :selected)
|
||||||
|
|
||||||
|
render_inline Admin::Proposals::ToggleSelectionComponent.new(proposal)
|
||||||
|
|
||||||
|
expect(page).to have_css "button[aria-pressed='true']"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is false for not selected proposals" do
|
||||||
|
proposal = create(:proposal)
|
||||||
|
|
||||||
|
render_inline Admin::Proposals::ToggleSelectionComponent.new(proposal)
|
||||||
|
|
||||||
|
expect(page).to have_css "button[aria-pressed='false']"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -23,18 +23,139 @@ describe Admin::BudgetInvestmentsController, :admin do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "PATCH update" do
|
describe "PATCH show_to_valuators" do
|
||||||
it "does not redirect on AJAX requests" do
|
let(:investment) { create(:budget_investment, :invisible_to_valuators) }
|
||||||
investment = create(:budget_investment)
|
|
||||||
|
|
||||||
patch :update, params: {
|
it "marks the investment as visible to valuators" do
|
||||||
id: investment,
|
expect do
|
||||||
budget_id: investment.budget,
|
patch :show_to_valuators, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
format: :json,
|
end.to change { investment.reload.visible_to_valuators? }.from(false).to(true)
|
||||||
budget_investment: { visible_to_valuators: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(response).not_to be_redirect
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify investments visible to valuators" do
|
||||||
|
investment.update!(visible_to_valuators: true)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :show_to_valuators, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.not_to change { investment.reload.visible_to_valuators? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_budget_budget_investments_path(investment.budget)
|
||||||
|
|
||||||
|
patch :show_to_valuators, params: { id: investment, budget_id: investment.budget }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_budget_budget_investments_path(investment.budget)
|
||||||
|
expect(flash[:notice]).to eq "Investment project updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH hide_from_valuators" do
|
||||||
|
let(:investment) { create(:budget_investment, :visible_to_valuators) }
|
||||||
|
|
||||||
|
it "marks the investment as visible to valuators" do
|
||||||
|
expect do
|
||||||
|
patch :hide_from_valuators, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.to change { investment.reload.visible_to_valuators? }.from(true).to(false)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify investments visible to valuators" do
|
||||||
|
investment.update!(visible_to_valuators: false)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :hide_from_valuators, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.not_to change { investment.reload.visible_to_valuators? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_budget_budget_investments_path(investment.budget)
|
||||||
|
|
||||||
|
patch :hide_from_valuators, params: { id: investment, budget_id: investment.budget }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_budget_budget_investments_path(investment.budget)
|
||||||
|
expect(flash[:notice]).to eq "Investment project updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH select" do
|
||||||
|
let(:investment) { create(:budget_investment, :feasible, :finished) }
|
||||||
|
|
||||||
|
it "selects the investment" do
|
||||||
|
expect do
|
||||||
|
patch :select, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.to change { investment.reload.selected? }.from(false).to(true)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify already selected investments" do
|
||||||
|
investment.update!(selected: true)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :select, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.not_to change { investment.reload.selected? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "uses the select/deselect authorization rules" do
|
||||||
|
investment.update!(valuation_finished: false)
|
||||||
|
|
||||||
|
patch :select, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
|
||||||
|
expect(flash[:alert]).to eq "You do not have permission to carry out the action " \
|
||||||
|
"'select' on Investment."
|
||||||
|
expect(investment).not_to be_selected
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_budget_budget_investments_path(investment.budget)
|
||||||
|
|
||||||
|
patch :select, params: { id: investment, budget_id: investment.budget }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_budget_budget_investments_path(investment.budget)
|
||||||
|
expect(flash[:notice]).to eq "Investment project updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH deselect" do
|
||||||
|
let(:investment) { create(:budget_investment, :feasible, :finished, :selected) }
|
||||||
|
|
||||||
|
it "deselects the investment" do
|
||||||
|
expect do
|
||||||
|
patch :deselect, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.to change { investment.reload.selected? }.from(true).to(false)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify non-selected investments" do
|
||||||
|
investment.update!(selected: false)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :deselect, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
end.not_to change { investment.reload.selected? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "uses the select/deselect authorization rules" do
|
||||||
|
investment.update!(valuation_finished: false)
|
||||||
|
|
||||||
|
patch :deselect, xhr: true, params: { id: investment, budget_id: investment.budget }
|
||||||
|
|
||||||
|
expect(flash[:alert]).to eq "You do not have permission to carry out the action " \
|
||||||
|
"'deselect' on Investment."
|
||||||
|
expect(investment).to be_selected
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_budget_budget_investments_path(investment.budget)
|
||||||
|
|
||||||
|
patch :deselect, params: { id: investment, budget_id: investment.budget }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_budget_budget_investments_path(investment.budget)
|
||||||
|
expect(flash[:notice]).to eq "Investment project updated successfully."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::Legislation::ProposalsController, :admin do
|
||||||
|
describe "PATCH select" do
|
||||||
|
let(:proposal) { create(:legislation_proposal) }
|
||||||
|
|
||||||
|
it "selects the proposal" do
|
||||||
|
expect do
|
||||||
|
patch :select, xhr: true, params: { id: proposal.id, process_id: proposal.process.id }
|
||||||
|
end.to change { proposal.reload.selected? }.from(false).to(true)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify already selected proposals" do
|
||||||
|
proposal.update!(selected: true)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :select, xhr: true, params: { id: proposal.id, process_id: proposal.process.id }
|
||||||
|
end.not_to change { proposal.reload.selected? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_proposals_path
|
||||||
|
|
||||||
|
patch :select, params: { id: proposal.id, process_id: proposal.process.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_proposals_path
|
||||||
|
expect(flash[:notice]).to eq "Proposal updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH deselect" do
|
||||||
|
let(:proposal) { create(:legislation_proposal, :selected) }
|
||||||
|
|
||||||
|
it "deselects the proposal" do
|
||||||
|
expect do
|
||||||
|
patch :deselect, xhr: true, params: { id: proposal.id, process_id: proposal.process.id }
|
||||||
|
end.to change { proposal.reload.selected? }.from(true).to(false)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify non-selected proposals" do
|
||||||
|
proposal.update!(selected: false)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :deselect, xhr: true, params: { id: proposal.id, process_id: proposal.process.id }
|
||||||
|
end.not_to change { proposal.reload.selected? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_proposals_path
|
||||||
|
|
||||||
|
patch :deselect, params: { id: proposal.id, process_id: proposal.process.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_proposals_path
|
||||||
|
expect(flash[:notice]).to eq "Proposal updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
61
spec/controllers/admin/proposals_controller_spec.rb
Normal file
61
spec/controllers/admin/proposals_controller_spec.rb
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe Admin::ProposalsController, :admin do
|
||||||
|
describe "PATCH select" do
|
||||||
|
let(:proposal) { create(:proposal) }
|
||||||
|
|
||||||
|
it "selects the proposal" do
|
||||||
|
expect do
|
||||||
|
patch :select, xhr: true, params: { id: proposal.id }
|
||||||
|
end.to change { proposal.reload.selected? }.from(false).to(true)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify already selected proposals" do
|
||||||
|
proposal.update!(selected: true)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :select, xhr: true, params: { id: proposal.id }
|
||||||
|
end.not_to change { proposal.reload.selected? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_proposals_path
|
||||||
|
|
||||||
|
patch :select, params: { id: proposal.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_proposals_path
|
||||||
|
expect(flash[:notice]).to eq "Proposal updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "PATCH deselect" do
|
||||||
|
let(:proposal) { create(:proposal, :selected) }
|
||||||
|
|
||||||
|
it "deselects the proposal" do
|
||||||
|
expect do
|
||||||
|
patch :deselect, xhr: true, params: { id: proposal.id }
|
||||||
|
end.to change { proposal.reload.selected? }.from(true).to(false)
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not modify non-selected proposals" do
|
||||||
|
proposal.update!(selected: false)
|
||||||
|
|
||||||
|
expect do
|
||||||
|
patch :deselect, xhr: true, params: { id: proposal.id }
|
||||||
|
end.not_to change { proposal.reload.selected? }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "redirects admins without JavaScript to the same page" do
|
||||||
|
request.env["HTTP_REFERER"] = admin_proposals_path
|
||||||
|
|
||||||
|
patch :deselect, params: { id: proposal.id }
|
||||||
|
|
||||||
|
expect(response).to redirect_to admin_proposals_path
|
||||||
|
expect(flash[:notice]).to eq "Proposal updated successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -177,5 +177,9 @@ FactoryBot.define do
|
|||||||
trait :hidden do
|
trait :hidden do
|
||||||
hidden_at { Time.current }
|
hidden_at { Time.current }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :selected do
|
||||||
|
selected { true }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -115,7 +115,11 @@ describe Abilities::Administrator do
|
|||||||
it { should_not be_able_to(:admin_update, finished_investment) }
|
it { should_not be_able_to(:admin_update, finished_investment) }
|
||||||
it { should_not be_able_to(:valuate, finished_investment) }
|
it { should_not be_able_to(:valuate, finished_investment) }
|
||||||
it { should_not be_able_to(:comment_valuation, finished_investment) }
|
it { should_not be_able_to(:comment_valuation, finished_investment) }
|
||||||
it { should_not be_able_to(:toggle_selection, finished_investment) }
|
|
||||||
|
it { should be_able_to([:select, :deselect], create(:budget_investment, :feasible, :finished)) }
|
||||||
|
it { should_not be_able_to([:select, :deselect], create(:budget_investment, :feasible, :open)) }
|
||||||
|
it { should_not be_able_to([:select, :deselect], create(:budget_investment, :unfeasible, :finished)) }
|
||||||
|
it { should_not be_able_to([:select, :deselect], finished_investment) }
|
||||||
|
|
||||||
it { should be_able_to(:destroy, proposal_image) }
|
it { should be_able_to(:destroy, proposal_image) }
|
||||||
it { should be_able_to(:destroy, proposal_document) }
|
it { should be_able_to(:destroy, proposal_document) }
|
||||||
|
|||||||
@@ -43,21 +43,6 @@ describe "Admin budget investments", :admin do
|
|||||||
expect(page).not_to have_content("€")
|
expect(page).not_to have_content("€")
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "If budget is finished do not show 'Selected' button" do
|
|
||||||
finished_budget = create(:budget, :finished)
|
|
||||||
budget_investment = create(:budget_investment, budget: finished_budget, cached_votes_up: 77)
|
|
||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget_id: finished_budget.id)
|
|
||||||
|
|
||||||
within("#budget_investment_#{budget_investment.id}") do
|
|
||||||
expect(page).to have_content(budget_investment.title)
|
|
||||||
expect(page).to have_content(budget_investment.heading.name)
|
|
||||||
expect(page).to have_content(budget_investment.id)
|
|
||||||
expect(page).to have_content(budget_investment.total_votes)
|
|
||||||
expect(page).not_to have_link("Selected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Display admin and valuator assignments" do
|
scenario "Display admin and valuator assignments" do
|
||||||
olga = create(:user, username: "Olga")
|
olga = create(:user, username: "Olga")
|
||||||
miriam = create(:user, username: "Miriam")
|
miriam = create(:user, username: "Miriam")
|
||||||
@@ -1422,62 +1407,19 @@ describe "Admin budget investments", :admin do
|
|||||||
expect(page).not_to have_content(feasible_vf_bi.title)
|
expect(page).not_to have_content(feasible_vf_bi.title)
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Showing the selection buttons" do
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
|
||||||
|
|
||||||
within("#budget_investment_#{unfeasible_bi.id}") do
|
|
||||||
expect(page).not_to have_link("Select")
|
|
||||||
expect(page).not_to have_link("Selected")
|
|
||||||
end
|
|
||||||
|
|
||||||
within("#budget_investment_#{feasible_bi.id}") do
|
|
||||||
expect(page).not_to have_link("Select")
|
|
||||||
expect(page).not_to have_link("Selected")
|
|
||||||
end
|
|
||||||
|
|
||||||
within("#budget_investment_#{feasible_vf_bi.id}") do
|
|
||||||
expect(page).to have_link("Select")
|
|
||||||
expect(page).not_to have_link("Selected")
|
|
||||||
end
|
|
||||||
|
|
||||||
within("#budget_investment_#{selected_bi.id}") do
|
|
||||||
expect(page).not_to have_link("Select")
|
|
||||||
expect(page).to have_link("Selected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Show only selected text when budget is finished" do
|
|
||||||
budget.update!(phase: "finished")
|
|
||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
|
||||||
|
|
||||||
within("#budget_investment_#{unfeasible_bi.id} #selection") do
|
|
||||||
expect(page).not_to have_content("Select")
|
|
||||||
expect(page).not_to have_content("Selected")
|
|
||||||
end
|
|
||||||
|
|
||||||
within("#budget_investment_#{feasible_bi.id} #selection") do
|
|
||||||
expect(page).not_to have_content("Select")
|
|
||||||
expect(page).not_to have_content("Selected")
|
|
||||||
end
|
|
||||||
|
|
||||||
within("#budget_investment_#{feasible_vf_bi.id} #selection") do
|
|
||||||
expect(page).not_to have_content("Select")
|
|
||||||
expect(page).not_to have_content("Selected")
|
|
||||||
end
|
|
||||||
|
|
||||||
within("#budget_investment_#{selected_bi.id} #selection") do
|
|
||||||
expect(page).not_to contain_exactly("Select")
|
|
||||||
expect(page).to have_content("Selected")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Selecting an investment" do
|
scenario "Selecting an investment" do
|
||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
within("#budget_investment_#{feasible_vf_bi.id}") do
|
expect(page).to have_content "Unfeasible project"
|
||||||
click_link("Select")
|
|
||||||
expect(page).to have_link("Selected")
|
within("tr", text: "Feasible, VF project") do
|
||||||
|
within("[data-field=selected]") do
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
|
||||||
|
click_button "Select Feasible, VF project"
|
||||||
|
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
click_link "Advanced filters"
|
click_link "Advanced filters"
|
||||||
@@ -1485,9 +1427,12 @@ describe "Admin budget investments", :admin do
|
|||||||
within("#advanced_filters") { check("Selected") }
|
within("#advanced_filters") { check("Selected") }
|
||||||
click_button("Filter")
|
click_button("Filter")
|
||||||
|
|
||||||
within("#budget_investment_#{feasible_vf_bi.id}") do
|
expect(page).not_to have_content "Unfeasible project"
|
||||||
expect(page).not_to have_link("Select")
|
|
||||||
expect(page).to have_link("Selected")
|
within("tr", text: "Feasible, VF project") do
|
||||||
|
within("[data-field=selected]") do
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1500,21 +1445,26 @@ describe "Admin budget investments", :admin do
|
|||||||
|
|
||||||
expect(page).to have_content("There are 2 investments")
|
expect(page).to have_content("There are 2 investments")
|
||||||
|
|
||||||
within("#budget_investment_#{selected_bi.id}") do
|
within("tr", text: "Selected project") do
|
||||||
click_link("Selected")
|
within("[data-field=selected]") do
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
|
||||||
expect(page).to have_link("Select")
|
click_button "Select Selected project"
|
||||||
|
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
click_button("Filter")
|
click_button "Filter"
|
||||||
expect(page).not_to have_content(selected_bi.title)
|
expect(page).not_to have_content "Selected project"
|
||||||
expect(page).to have_content("There is 1 investment")
|
expect(page).to have_content "There is 1 investment"
|
||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
within("#budget_investment_#{selected_bi.id}") do
|
within("tr", text: "Selected project") do
|
||||||
expect(page).to have_link("Select")
|
within("[data-field=selected]") do
|
||||||
expect(page).not_to have_link("Selected")
|
expect(page).to have_content "No"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1526,10 +1476,12 @@ describe "Admin budget investments", :admin do
|
|||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
within("#budget_investment_#{selected_bi.id}") do
|
within("tr", text: "Selected project") do
|
||||||
click_link("Selected")
|
within("[data-field=selected]") do
|
||||||
|
click_button "Select Selected project"
|
||||||
|
|
||||||
expect(page).to have_link "Select"
|
expect(page).to have_content "No"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
click_link("Next")
|
click_link("Next")
|
||||||
@@ -1545,8 +1497,8 @@ describe "Admin budget investments", :admin do
|
|||||||
|
|
||||||
let(:heading) { create(:budget_heading, budget: budget) }
|
let(:heading) { create(:budget_heading, budget: budget) }
|
||||||
|
|
||||||
let(:investment1) { create(:budget_investment, heading: heading) }
|
let(:investment1) { create(:budget_investment, heading: heading, title: "Investment 1") }
|
||||||
let(:investment2) { create(:budget_investment, heading: heading) }
|
let(:investment2) { create(:budget_investment, heading: heading, title: "Investment 2") }
|
||||||
|
|
||||||
scenario "Mark as visible to valuator" do
|
scenario "Mark as visible to valuator" do
|
||||||
investment1.valuators << valuator
|
investment1.valuators << valuator
|
||||||
@@ -1559,17 +1511,22 @@ describe "Admin budget investments", :admin do
|
|||||||
check "Under valuation"
|
check "Under valuation"
|
||||||
click_button "Filter"
|
click_button "Filter"
|
||||||
|
|
||||||
within("#budget_investment_#{investment1.id}") do
|
within("tr", text: "Investment 1") do
|
||||||
check "budget_investment_visible_to_valuators"
|
within("[data-field=visible_to_valuators]") do
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
|
||||||
|
click_button "Show Investment 1 to valuators"
|
||||||
|
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
refresh
|
||||||
click_link "Advanced filters"
|
|
||||||
check "Under valuation"
|
|
||||||
click_button "Filter"
|
|
||||||
|
|
||||||
within("#budget_investment_#{investment1.id}") do
|
within("tr", text: "Investment 1") do
|
||||||
expect(find("#budget_investment_visible_to_valuators")).to be_checked
|
within("[data-field=visible_to_valuators]") do
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1608,18 +1565,22 @@ describe "Admin budget investments", :admin do
|
|||||||
check "Under valuation"
|
check "Under valuation"
|
||||||
click_button "Filter"
|
click_button "Filter"
|
||||||
|
|
||||||
within("#budget_investment_#{investment1.id}") do
|
within("tr", text: "Investment 1") do
|
||||||
uncheck "budget_investment_visible_to_valuators"
|
within("[data-field=visible_to_valuators]") do
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
|
||||||
|
click_button "Show Investment 1 to valuators"
|
||||||
|
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
refresh
|
||||||
|
|
||||||
click_link "Advanced filters"
|
within("tr", text: "Investment 1") do
|
||||||
check "Under valuation"
|
within("[data-field=visible_to_valuators]") do
|
||||||
click_button "Filter"
|
expect(page).to have_content "No"
|
||||||
|
end
|
||||||
within("#budget_investment_#{investment1.id}") do
|
|
||||||
expect(find("#budget_investment_visible_to_valuators")).not_to be_checked
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1631,42 +1592,44 @@ describe "Admin budget investments", :admin do
|
|||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
within "tr", text: "Visible" do
|
within "tr", text: "Visible" do
|
||||||
within "td[data-field=visible_to_valuators]" do
|
within "[data-field=visible_to_valuators]" do
|
||||||
expect(page).to have_text "Yes"
|
expect(page).to have_text "Yes"
|
||||||
expect(page).not_to have_field "budget_investment_visible_to_valuators"
|
expect(page).not_to have_button
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
within "tr", text: "Invisible" do
|
within "tr", text: "Invisible" do
|
||||||
within "td[data-field=visible_to_valuators]" do
|
within "[data-field=visible_to_valuators]" do
|
||||||
expect(page).to have_text "No"
|
expect(page).to have_text "No"
|
||||||
expect(page).not_to have_field "budget_investment_visible_to_valuators"
|
expect(page).not_to have_button
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Showing the valuating checkbox" do
|
scenario "Showing the valuating checkbox" do
|
||||||
investment1 = create(:budget_investment, :with_administrator, :with_valuator, :visible_to_valuators,
|
investment1.valuators << valuator
|
||||||
budget: budget)
|
investment2.valuators << valuator
|
||||||
investment2 = create(:budget_investment, :with_administrator, :with_valuator, :invisible_to_valuators,
|
investment1.update!(administrator: admin, visible_to_valuators: true)
|
||||||
budget: budget)
|
investment2.update!(administrator: admin, visible_to_valuators: false)
|
||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
expect(page).to have_css("#budget_investment_visible_to_valuators")
|
|
||||||
|
|
||||||
click_link "Advanced filters"
|
click_link "Advanced filters"
|
||||||
check "Under valuation"
|
check "Under valuation"
|
||||||
click_button "Filter"
|
click_button "Filter"
|
||||||
|
|
||||||
within("#budget_investment_#{investment1.id}") do
|
within "tr", text: "Investment 1" do
|
||||||
valuating_checkbox = find("#budget_investment_visible_to_valuators")
|
within "[data-field=visible_to_valuators]" do
|
||||||
expect(valuating_checkbox).to be_checked
|
expect(page).to have_content "Yes"
|
||||||
|
expect(page).to have_css "button[aria-pressed='true']"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
within("#budget_investment_#{investment2.id}") do
|
within "tr", text: "Investment 2" do
|
||||||
valuating_checkbox = find("#budget_investment_visible_to_valuators")
|
within "[data-field=visible_to_valuators]" do
|
||||||
expect(valuating_checkbox).not_to be_checked
|
expect(page).to have_content "No"
|
||||||
|
expect(page).to have_css "button[aria-pressed='false']"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1676,8 +1639,14 @@ describe "Admin budget investments", :admin do
|
|||||||
|
|
||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
within("#budget_investment_#{investment1.id}") do
|
within "tr", text: "Investment 1" do
|
||||||
check "budget_investment_visible_to_valuators"
|
within "[data-field=visible_to_valuators]" do
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
|
||||||
|
click_button "Show Investment 1 to valuators"
|
||||||
|
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
visit edit_admin_budget_budget_investment_path(budget, investment1)
|
visit edit_admin_budget_budget_investment_path(budget, investment1)
|
||||||
@@ -1867,13 +1836,18 @@ describe "Admin budget investments", :admin do
|
|||||||
within("#js-columns-selector-wrapper") { uncheck "Title" }
|
within("#js-columns-selector-wrapper") { uncheck "Title" }
|
||||||
|
|
||||||
within("#budget_investment_#{investment.id}") do
|
within("#budget_investment_#{investment.id}") do
|
||||||
click_link "Selected"
|
within("[data-field=selected]") do
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
|
||||||
expect(page).to have_link "Select"
|
click_button "Select Don't display me, please!"
|
||||||
expect(page).not_to have_content "Don't display me, please!"
|
|
||||||
|
expect(page).to have_content "No"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Don't display me, please!"
|
||||||
|
end
|
||||||
|
|
||||||
scenario "When restoring the page from browser history renders columns selectors only once" do
|
scenario "When restoring the page from browser history renders columns selectors only once" do
|
||||||
visit admin_budget_budget_investments_path(budget)
|
visit admin_budget_budget_investments_path(budget)
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ describe "Admin collaborative legislation", :admin do
|
|||||||
expect(page).to have_content(proposal.title)
|
expect(page).to have_content(proposal.title)
|
||||||
expect(page).to have_content(proposal.id)
|
expect(page).to have_content(proposal.id)
|
||||||
expect(page).to have_content(proposal.cached_votes_score)
|
expect(page).to have_content(proposal.cached_votes_score)
|
||||||
expect(page).to have_content("Select")
|
expect(page).to have_content("No")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Selecting legislation proposals" do
|
scenario "Selecting legislation proposals" do
|
||||||
proposal = create(:legislation_proposal, cached_votes_score: 10)
|
proposal = create(:legislation_proposal, title: "Add more accessibility tests")
|
||||||
|
|
||||||
visit admin_legislation_process_proposals_path(proposal.legislation_process_id)
|
visit admin_legislation_process_proposals_path(proposal.legislation_process_id)
|
||||||
click_link "Select"
|
click_button "Select Add more accessibility tests"
|
||||||
|
|
||||||
within "#legislation_proposal_#{proposal.id}" do
|
within "#legislation_proposal_#{proposal.id}" do
|
||||||
expect(page).to have_content("Selected")
|
expect(page).to have_content "Yes"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -22,31 +22,39 @@ describe "Admin proposals", :admin do
|
|||||||
end
|
end
|
||||||
|
|
||||||
scenario "Select a proposal" do
|
scenario "Select a proposal" do
|
||||||
proposal = create(:proposal)
|
proposal = create(:proposal, title: "Forbid door-to-door sales")
|
||||||
|
|
||||||
visit admin_proposals_path
|
visit admin_proposals_path
|
||||||
|
|
||||||
within("#proposal_#{proposal.id}") { click_link "Select" }
|
within("#proposal_#{proposal.id}") do
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
|
||||||
within("#proposal_#{proposal.id}") { expect(page).to have_link "Selected" }
|
click_button "Select Forbid door-to-door sales"
|
||||||
|
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
|
|
||||||
refresh
|
refresh
|
||||||
|
|
||||||
within("#proposal_#{proposal.id}") { expect(page).to have_link "Selected" }
|
within("#proposal_#{proposal.id}") { expect(page).to have_content "Yes" }
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Unselect a proposal" do
|
scenario "Unselect a proposal" do
|
||||||
proposal = create(:proposal, :selected)
|
proposal = create(:proposal, :selected, title: "Allow door-to-door sales")
|
||||||
|
|
||||||
visit admin_proposals_path
|
visit admin_proposals_path
|
||||||
|
|
||||||
within("#proposal_#{proposal.id}") { click_link "Selected" }
|
within("#proposal_#{proposal.id}") do
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
|
||||||
within("#proposal_#{proposal.id}") { expect(page).to have_link "Select" }
|
click_button "Select Allow door-to-door sales"
|
||||||
|
|
||||||
|
expect(page).to have_content "No"
|
||||||
|
end
|
||||||
|
|
||||||
refresh
|
refresh
|
||||||
|
|
||||||
within("#proposal_#{proposal.id}") { expect(page).to have_link "Select" }
|
within("#proposal_#{proposal.id}") { expect(page).to have_content "No" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
require "rails_helper"
|
|
||||||
|
|
||||||
describe "investment row" do
|
|
||||||
it "uses a JSON request to update visible to valuators" do
|
|
||||||
investment = create(:budget_investment)
|
|
||||||
@budget = investment.budget
|
|
||||||
sign_in(create(:administrator).user)
|
|
||||||
|
|
||||||
render "admin/budget_investments/select_investment", investment: investment
|
|
||||||
|
|
||||||
expect(rendered).to have_css "form[action$='json'] input[name$='[visible_to_valuators]']"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Reference in New Issue
Block a user