Merge pull request #5498 from consuldemocracy/toggle_switch

Use a switch control to toggle selections
This commit is contained in:
Javi Martín
2024-10-28 14:19:58 +01:00
committed by GitHub
52 changed files with 966 additions and 436 deletions

View File

@@ -80,9 +80,6 @@
App.ColumnsSelector.toggleColumn(event);
}
});
$(".column-selectable").on("inserted", function() {
App.ColumnsSelector.initColumns();
});
},
destroy: function() {
$("#js-columns-selector-wrapper").children(":not(#column_selector_item_template)").remove();

View File

@@ -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;
}
}

View File

@@ -85,7 +85,7 @@
@include regular-button;
border-radius: $line-height;
font-weight: bold;
min-width: rem-calc(100);
min-width: 6em;
position: relative;
&::after {

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View 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

View File

@@ -0,0 +1,5 @@
<% if can?(action, investment) %>
<%= render Admin::ToggleSwitchComponent.new(action, investment, pressed: selected?, **options) %>
<% elsif selected? %>
<%= selected_text %>
<% end %>

View File

@@ -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

View File

@@ -0,0 +1,5 @@
<% if can?(:admin_update, investment) %>
<%= render Admin::ToggleSwitchComponent.new(action, investment, pressed: visible_to_valuators?, **options) %>
<% else %>
<%= text %>
<% end %>

View File

@@ -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

View File

@@ -0,0 +1 @@
<%= render Admin::ToggleSwitchComponent.new(action, proposal, pressed: selected?, **options) %>

View 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

View File

@@ -1 +1 @@
<%= render Admin::ActionComponent.new(action, record, **default_options.merge(options)) %>
<%= render Admin::ActionComponent.new(action, record, **html_options) %>

View File

@@ -25,7 +25,11 @@ class Admin::ToggleSwitchComponent < ApplicationComponent
method: :patch,
remote: true,
"aria-pressed": pressed?,
form_class: "toggle-switch"
form_class: "toggle-switch #{options[:form_class]}".strip
}
end
def html_options
default_options.merge(options.except(:form_class))
end
end

View File

@@ -6,19 +6,18 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
feature_flag :budgets
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_investment, only: [:show, :edit, :update, :toggle_selection]
before_action :load_investment, except: [:index]
before_action :load_ballot, only: [:show, :index]
before_action :parse_valuation_filters
before_action :load_investments, only: [:index, :toggle_selection]
before_action :load_investments, only: :index
def index
load_tags
respond_to do |format|
format.html
format.js
format.csv do
send_data Budget::Investment::Exporter.new(@investments).to_csv,
filename: "budget_investments.csv"
@@ -40,32 +39,57 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
def update
authorize! :admin_update, @investment
respond_to do |format|
format.html do
if @investment.update(budget_investment_params)
redirect_to admin_budget_budget_investment_path(@budget,
@investment,
Budget::Investment.filter_params(params).to_h),
notice: t("flash.actions.update.budget_investment")
else
load_staff
load_valuator_groups
load_tags
render :edit
end
end
format.json do
@investment.update!(budget_investment_params)
end
if @investment.update(budget_investment_params)
redirect_to admin_budget_budget_investment_path(@budget,
@investment,
Budget::Investment.filter_params(params).to_h),
notice: t("flash.actions.update.budget_investment")
else
load_staff
load_valuator_groups
load_tags
render :edit
end
end
def toggle_selection
authorize! :toggle_selection, @investment
@investment.toggle :selected
@investment.save!
load_investments
def show_to_valuators
authorize! :admin_update, @investment
@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
def hide_from_valuators
authorize! :admin_update, @investment
@investment.update!(visible_to_valuators: false)
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
private
@@ -96,7 +120,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
def allowed_params
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: []]
[*attributes, translation_params(Budget::Investment)]
end

View File

@@ -8,8 +8,21 @@ class Admin::Legislation::ProposalsController < Admin::Legislation::BaseControll
@proposals = @proposals.send("sort_by_#{@current_order}").page(params[:page])
end
def toggle_selection
@proposal.toggle :selected
@proposal.save!
def select
@proposal.update!(selected: true)
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

View File

@@ -19,9 +19,22 @@ class Admin::ProposalsController < Admin::BaseController
end
end
def toggle_selection
@proposal.toggle :selected
@proposal.save!
def select
@proposal.update!(selected: true)
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
private

View File

@@ -3,18 +3,6 @@ module BudgetInvestmentsHelper
params.map { |af| t("admin.budget_investments.index.filters.#{af}") }.join(", ")
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)
if sort_by.to_s == params[:sort_by]
if direction == "desc"

View File

@@ -1,11 +1,4 @@
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 = {})
case namespace
when "management"

View File

@@ -64,25 +64,6 @@ module ProposalsHelper
proposals_current_view == "default" ? "minimal" : "default"
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)
if proposal.image.present?
if params[:selected].present?

View File

@@ -71,10 +71,13 @@ module Abilities
can [:read, :create, :update, :destroy], Budget::Group
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
cannot [:admin_update, :toggle_selection, :valuate, :comment_valuation],
cannot [:admin_update, :valuate, :comment_valuation],
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

View File

@@ -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 %>

View File

@@ -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 %>

View File

@@ -12,6 +12,4 @@
<%= render "/shared/filter_subnav", i18n_namespace: "admin.budget_investments.index" %>
<div id="investments">
<%= render "investments" %>
</div>
<%= render Admin::BudgetInvestments::InvestmentsComponent.new(@budget, @investments) %>

View File

@@ -1 +0,0 @@
$("#investments").html("<%= j render("admin/budget_investments/investments") %>");

View File

@@ -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)) %>

View File

@@ -0,0 +1,4 @@
<%= render "admin/shared/toggle_switch",
record: @investment,
form_class: "visible-to-valuators",
new_content: render(Admin::BudgetInvestments::ToggleVisibleToValuatorsComponent.new(@investment)) %>

View File

@@ -1,5 +1,3 @@
var replacement = $("<%= j render Admin::BudgetPhases::ToggleEnabledComponent.new(@phase) %>");
var form = $("#<%= dom_id(@phase) %> .toggle-switch");
form.replaceWith(replacement);
replacement.find("[type='submit']").focus();
<%= render "admin/shared/toggle_switch",
record: @phase,
new_content: render(Admin::BudgetPhases::ToggleEnabledComponent.new(@phase)) %>

View File

@@ -19,7 +19,7 @@
<td class="text-center"><%= proposal.id %></td>
<td><%= proposal.title %></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>
<% end %>
</tbody>

View File

@@ -1 +0,0 @@
<%= link_to_toggle_proposal_selection(proposal) %>

View File

@@ -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)) %>

View File

@@ -1 +0,0 @@
<%= link_to_toggle_proposal_selection(proposal) %>

View File

@@ -27,7 +27,7 @@
<td><%= link_to proposal.title, admin_proposal_path(proposal) %></td>
<td><%= proposal.author.username %></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>
<% end %>
</tbody>

View File

@@ -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)) %>

View 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();

View File

@@ -24,7 +24,7 @@ module ActionDispatch::Routing::UrlFor
end
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::Question::Option::Video Poll::Shift SDG::LocalTarget].include?(resource.class.name)
resolve = resolve_for(resource)

View File

@@ -16,6 +16,8 @@ en:
unmark_featured: Unmark featured
edit: Edit
configure: Configure
select: Select
show_to_valuators: "Show %{name} to valuators"
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."
banners:
@@ -268,7 +270,6 @@ en:
unfeasible: "Unfeasible"
undecided: "Undecided"
selected: "Selected"
select: "Select"
list:
id: ID
title: Title
@@ -1294,7 +1295,6 @@ en:
title: Proposals
id: ID
author: Author
select: Select
selected: Selected
milestones: Milestones
no_proposals: There are no proposals.

View File

@@ -16,6 +16,8 @@ es:
unmark_featured: Quitar destacado
edit: Editar
configure: Configurar
select: Seleccionar
show_to_valuators: "Mostrar %{name} a evaluadores"
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."
banners:
@@ -268,7 +270,6 @@ es:
unfeasible: "Inviable"
undecided: "Sin decidir"
selected: "Seleccionado"
select: "Seleccionar"
list:
id: ID
title: Título
@@ -1295,7 +1296,6 @@ es:
id: ID
author: Autor
milestones: Hitos
select: Seleccionar
selected: Seleccionada
no_proposals: No hay propuestas.
show:

View File

@@ -32,7 +32,11 @@ namespace :admin do
resources :debates, only: [:index, :show]
resources :proposals, only: [:index, :show, :update] do
member { patch :toggle_selection }
member do
patch :select
patch :deselect
end
resources :milestones, controller: "proposal_milestones"
resources :progress_bars, except: :show, controller: "proposal_progress_bars"
end
@@ -62,7 +66,12 @@ namespace :admin do
end
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 :milestones, controller: "budget_investment_milestones"
@@ -232,7 +241,10 @@ namespace :admin do
resources :processes do
resources :questions
resources :proposals do
member { patch :toggle_selection }
member do
patch :select
patch :deselect
end
end
resources :draft_versions
resources :milestones

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -23,18 +23,139 @@ describe Admin::BudgetInvestmentsController, :admin do
end
end
describe "PATCH update" do
it "does not redirect on AJAX requests" do
investment = create(:budget_investment)
describe "PATCH show_to_valuators" do
let(:investment) { create(:budget_investment, :invisible_to_valuators) }
patch :update, params: {
id: investment,
budget_id: investment.budget,
format: :json,
budget_investment: { visible_to_valuators: true }
}
it "marks the investment as visible to valuators" do
expect do
patch :show_to_valuators, xhr: true, params: { id: investment, budget_id: investment.budget }
end.to change { investment.reload.visible_to_valuators? }.from(false).to(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

View File

@@ -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

View 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

View File

@@ -177,5 +177,9 @@ FactoryBot.define do
trait :hidden do
hidden_at { Time.current }
end
trait :selected do
selected { true }
end
end
end

View File

@@ -115,7 +115,11 @@ describe Abilities::Administrator do
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(: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_document) }

View File

@@ -43,21 +43,6 @@ describe "Admin budget investments", :admin do
expect(page).not_to have_content("")
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
olga = create(:user, username: "Olga")
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)
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
visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{feasible_vf_bi.id}") do
click_link("Select")
expect(page).to have_link("Selected")
expect(page).to have_content "Unfeasible project"
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
click_link "Advanced filters"
@@ -1485,9 +1427,12 @@ describe "Admin budget investments", :admin do
within("#advanced_filters") { check("Selected") }
click_button("Filter")
within("#budget_investment_#{feasible_vf_bi.id}") do
expect(page).not_to have_link("Select")
expect(page).to have_link("Selected")
expect(page).not_to have_content "Unfeasible project"
within("tr", text: "Feasible, VF project") do
within("[data-field=selected]") do
expect(page).to have_content "Yes"
end
end
end
@@ -1500,21 +1445,26 @@ describe "Admin budget investments", :admin do
expect(page).to have_content("There are 2 investments")
within("#budget_investment_#{selected_bi.id}") do
click_link("Selected")
within("tr", text: "Selected project") do
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
click_button("Filter")
expect(page).not_to have_content(selected_bi.title)
expect(page).to have_content("There is 1 investment")
click_button "Filter"
expect(page).not_to have_content "Selected project"
expect(page).to have_content "There is 1 investment"
visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{selected_bi.id}") do
expect(page).to have_link("Select")
expect(page).not_to have_link("Selected")
within("tr", text: "Selected project") do
within("[data-field=selected]") do
expect(page).to have_content "No"
end
end
end
@@ -1526,10 +1476,12 @@ describe "Admin budget investments", :admin do
visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{selected_bi.id}") do
click_link("Selected")
within("tr", text: "Selected project") do
within("[data-field=selected]") do
click_button "Select Selected project"
expect(page).to have_link "Select"
expect(page).to have_content "No"
end
end
click_link("Next")
@@ -1545,8 +1497,8 @@ describe "Admin budget investments", :admin do
let(:heading) { create(:budget_heading, budget: budget) }
let(:investment1) { create(:budget_investment, heading: heading) }
let(:investment2) { create(:budget_investment, heading: heading) }
let(:investment1) { create(:budget_investment, heading: heading, title: "Investment 1") }
let(:investment2) { create(:budget_investment, heading: heading, title: "Investment 2") }
scenario "Mark as visible to valuator" do
investment1.valuators << valuator
@@ -1559,17 +1511,22 @@ describe "Admin budget investments", :admin do
check "Under valuation"
click_button "Filter"
within("#budget_investment_#{investment1.id}") do
check "budget_investment_visible_to_valuators"
within("tr", text: "Investment 1") do
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
visit admin_budget_budget_investments_path(budget)
click_link "Advanced filters"
check "Under valuation"
click_button "Filter"
refresh
within("#budget_investment_#{investment1.id}") do
expect(find("#budget_investment_visible_to_valuators")).to be_checked
within("tr", text: "Investment 1") do
within("[data-field=visible_to_valuators]") do
expect(page).to have_content "Yes"
end
end
end
@@ -1608,18 +1565,22 @@ describe "Admin budget investments", :admin do
check "Under valuation"
click_button "Filter"
within("#budget_investment_#{investment1.id}") do
uncheck "budget_investment_visible_to_valuators"
within("tr", text: "Investment 1") do
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
visit admin_budget_budget_investments_path(budget)
refresh
click_link "Advanced filters"
check "Under valuation"
click_button "Filter"
within("#budget_investment_#{investment1.id}") do
expect(find("#budget_investment_visible_to_valuators")).not_to be_checked
within("tr", text: "Investment 1") do
within("[data-field=visible_to_valuators]") do
expect(page).to have_content "No"
end
end
end
@@ -1631,42 +1592,44 @@ describe "Admin budget investments", :admin do
visit admin_budget_budget_investments_path(budget)
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).not_to have_field "budget_investment_visible_to_valuators"
expect(page).not_to have_button
end
end
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).not_to have_field "budget_investment_visible_to_valuators"
expect(page).not_to have_button
end
end
end
scenario "Showing the valuating checkbox" do
investment1 = create(:budget_investment, :with_administrator, :with_valuator, :visible_to_valuators,
budget: budget)
investment2 = create(:budget_investment, :with_administrator, :with_valuator, :invisible_to_valuators,
budget: budget)
investment1.valuators << valuator
investment2.valuators << valuator
investment1.update!(administrator: admin, visible_to_valuators: true)
investment2.update!(administrator: admin, visible_to_valuators: false)
visit admin_budget_budget_investments_path(budget)
expect(page).to have_css("#budget_investment_visible_to_valuators")
click_link "Advanced filters"
check "Under valuation"
click_button "Filter"
within("#budget_investment_#{investment1.id}") do
valuating_checkbox = find("#budget_investment_visible_to_valuators")
expect(valuating_checkbox).to be_checked
within "tr", text: "Investment 1" do
within "[data-field=visible_to_valuators]" do
expect(page).to have_content "Yes"
expect(page).to have_css "button[aria-pressed='true']"
end
end
within("#budget_investment_#{investment2.id}") do
valuating_checkbox = find("#budget_investment_visible_to_valuators")
expect(valuating_checkbox).not_to be_checked
within "tr", text: "Investment 2" do
within "[data-field=visible_to_valuators]" do
expect(page).to have_content "No"
expect(page).to have_css "button[aria-pressed='false']"
end
end
end
@@ -1676,8 +1639,14 @@ describe "Admin budget investments", :admin do
visit admin_budget_budget_investments_path(budget)
within("#budget_investment_#{investment1.id}") do
check "budget_investment_visible_to_valuators"
within "tr", text: "Investment 1" do
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
visit edit_admin_budget_budget_investment_path(budget, investment1)
@@ -1867,11 +1836,16 @@ describe "Admin budget investments", :admin do
within("#js-columns-selector-wrapper") { uncheck "Title" }
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"
expect(page).not_to have_content "Don't display me, please!"
click_button "Select Don't display me, please!"
expect(page).to have_content "No"
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

View File

@@ -11,18 +11,18 @@ describe "Admin collaborative legislation", :admin do
expect(page).to have_content(proposal.title)
expect(page).to have_content(proposal.id)
expect(page).to have_content(proposal.cached_votes_score)
expect(page).to have_content("Select")
expect(page).to have_content("No")
end
end
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)
click_link "Select"
click_button "Select Add more accessibility tests"
within "#legislation_proposal_#{proposal.id}" do
expect(page).to have_content("Selected")
expect(page).to have_content "Yes"
end
end

View File

@@ -22,31 +22,39 @@ describe "Admin proposals", :admin do
end
scenario "Select a proposal" do
proposal = create(:proposal)
proposal = create(:proposal, title: "Forbid door-to-door sales")
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
within("#proposal_#{proposal.id}") { expect(page).to have_link "Selected" }
within("#proposal_#{proposal.id}") { expect(page).to have_content "Yes" }
end
scenario "Unselect a proposal" do
proposal = create(:proposal, :selected)
proposal = create(:proposal, :selected, title: "Allow door-to-door sales")
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
within("#proposal_#{proposal.id}") { expect(page).to have_link "Select" }
within("#proposal_#{proposal.id}") { expect(page).to have_content "No" }
end
end

View File

@@ -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