Merge pull request #4549 from consul/investment_votes

Improve accessibility in support investment button
This commit is contained in:
Javi Martín
2021-06-14 13:45:31 +02:00
committed by GitHub
12 changed files with 168 additions and 87 deletions

View File

@@ -815,12 +815,20 @@
font-size: $base-font-size;
font-weight: bold;
&:disabled {
opacity: 1;
}
&:hover {
background: $budget-hover;
color: #fff;
cursor: pointer;
}
&:focus {
outline: $outline-focus;
}
&:active {
opacity: 0.75;
}

View File

@@ -0,0 +1,52 @@
<div class="supports js-participation">
<span class="total-supports <%= "no-button" unless voting_allowed? || user_voted_for? %>">
<%= t("budgets.investments.investment.supports", count: investment.total_votes) %>
</span>
<div class="in-favor">
<% if user_voted_for? %>
<div class="supported callout success">
<%= t("budgets.investments.investment.already_supported") %>
</div>
<% elsif investment.should_show_votes? %>
<%= button_to t("budgets.investments.investment.give_support"), vote_url,
class: "button button-support small expanded",
title: t("budgets.investments.investment.support_title"),
method: "post",
remote: !display_support_alert?,
data: ({ confirm: confirm_vote_message } if display_support_alert?),
disabled: !current_user,
"aria-label": support_aria_label %>
<% end %>
</div>
<% if reason.present? && !user_voted_for? %>
<div tabindex="0">
<div class="js-participation-not-allowed participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<small>
<%= sanitize(t("votes.budget_investments.#{reason}",
count: investment.group.max_votable_headings,
verify_account: link_to_verify_account,
signin: link_to_signin,
signup: link_to_signup,
supported_headings: (current_user && current_user.headings_voted_within_group(investment.group).map(&:name).sort.to_sentence)
)) %>
</small>
</p>
</div>
</div>
<% end %>
<% if user_voted_for? && setting["twitter_handle"] %>
<div class="share-supported">
<%= render "shared/social_share",
title: investment.title,
image_url: image_absolute_url(investment.image, :thumb),
url: budget_investment_url(investment.budget, investment),
description: investment.title,
mobile: investment.title %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,39 @@
class Budgets::Investments::VotesComponent < ApplicationComponent
attr_reader :investment, :investment_votes, :vote_url
delegate :current_user, :voted_for?, :image_absolute_url,
:link_to_verify_account, :link_to_signin, :link_to_signup, to: :helpers
def initialize(investment, investment_votes:, vote_url:)
@investment = investment
@investment_votes = investment_votes
@vote_url = vote_url
end
private
def reason
@reason ||= investment.reason_for_not_being_selectable_by(current_user)
end
def voting_allowed?
reason != :not_voting_allowed
end
def user_voted_for?
@user_voted_for ||= voted_for?(investment_votes, investment)
end
def display_support_alert?
current_user &&
!current_user.voted_in_group?(investment.group) &&
investment.group.headings.count > 1
end
def confirm_vote_message
t("budgets.investments.investment.confirm_group", count: investment.group.max_votable_headings)
end
def support_aria_label
t("budgets.investments.investment.support_label", investment: investment.title)
end
end

View File

@@ -1,5 +0,0 @@
module AccessibilityHelper
def css_for_aria_hidden(reason)
reason.present? ? "true" : ""
end
end

View File

@@ -54,12 +54,6 @@ module BudgetsHelper
end
end
def display_support_alert?(investment)
current_user &&
!current_user.voted_in_group?(investment.group) &&
investment.group.headings.count > 1
end
def budget_subnav_items_for(budget)
{
results: t("budgets.results.link"),

View File

@@ -1,56 +1,5 @@
<% reason = investment.reason_for_not_being_selectable_by(current_user) %>
<% voting_allowed = true unless reason.presence == :not_voting_allowed %>
<% user_voted_for = voted_for?(investment_votes, investment) %>
<div class="supports js-participation">
<span class="total-supports <%= "no-button" unless voting_allowed || user_voted_for %>">
<%= t("budgets.investments.investment.supports", count: investment.total_votes) %>
</span>
<div class="in-favor js-in-favor">
<% if user_voted_for %>
<div class="supported callout success">
<%= t("budgets.investments.investment.already_supported") %>
</div>
<% elsif investment.should_show_votes? %>
<%= link_to vote_url,
class: "button button-support small expanded",
title: t("budgets.investments.investment.support_title"),
method: "post",
remote: (display_support_alert?(investment) ? false : true),
data: (display_support_alert?(investment) ? {
confirm: t("budgets.investments.investment.confirm_group", count: investment.group.max_votable_headings) } : nil),
"aria-hidden" => css_for_aria_hidden(reason) do %>
<%= t("budgets.investments.investment.give_support") %>
<% end %>
<% end %>
</div>
<% if reason.present? && !user_voted_for %>
<div class="js-participation-not-allowed participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<small>
<%= sanitize(t("votes.budget_investments.#{reason}",
count: investment.group.max_votable_headings,
verify_account: link_to_verify_account,
signin: link_to_signin,
signup: link_to_signup,
supported_headings: (current_user && current_user.headings_voted_within_group(investment.group).map(&:name).sort.to_sentence)
)) %>
</small>
</p>
</div>
<% end %>
<% if user_voted_for && setting["twitter_handle"] %>
<div class="share-supported">
<%= render "shared/social_share",
title: investment.title,
image_url: image_absolute_url(investment.image, :thumb),
url: budget_investment_url(investment.budget, investment),
description: investment.title,
mobile: investment.title %>
</div>
<% end %>
</div>
<%= render Budgets::Investments::VotesComponent.new(
investment,
investment_votes: investment_votes,
vote_url: vote_url
) %>

View File

@@ -158,6 +158,7 @@ en:
already_added: You have already added this investment project
already_supported: You have already supported this investment project. Share it!
support_title: Support this project
support_label: "Support %{investment}"
confirm_group:
one: "You can only support investments in %{count} district. If you continue you cannot change the election of your district. Are you sure?"
other: "You can only support investments in %{count} districts. If you continue you cannot change the election of your district. Are you sure?"

View File

@@ -158,6 +158,7 @@ es:
already_added: Ya has añadido este proyecto de gasto
already_supported: Ya has apoyado este proyecto de gasto. ¡Compártelo!
support_title: Apoyar este proyecto
support_label: "Apoyar %{investment}"
confirm_group:
one: "Sólo puedes apoyar proyectos en %{count} distrito. Si sigues adelante no podrás cambiar la elección de este distrito. ¿Estás seguro/a?"
other: "Sólo puedes apoyar proyectos en %{count} distritos. Si sigues adelante no podrás cambiar la elección de este distrito. ¿Estás seguro/a?"

View File

@@ -0,0 +1,32 @@
require "rails_helper"
describe Budgets::Investments::VotesComponent, type: :component do
describe "vote link" do
context "when investment shows votes" do
let(:investment) { create(:budget_investment, title: "Renovate sidewalks in Main Street") }
let(:component) do
Budgets::Investments::VotesComponent.new(investment, investment_votes: [], vote_url: "/")
end
before { allow(investment).to receive(:should_show_votes?).and_return(true) }
it "displays a button to support the investment to identified users" do
allow(controller).to receive(:current_user).and_return(create(:user))
render_inline component
expect(page).to have_button count: 1
expect(page).to have_button "Support", title: "Support this project", disabled: false
expect(page).to have_button "Support Renovate sidewalks in Main Street"
end
it "disables the button to support the investment to unidentified users" do
allow(controller).to receive(:current_user).and_return(nil)
render_inline component
expect(page).to have_button "Support", disabled: true
end
end
end
end

View File

@@ -1113,7 +1113,9 @@ describe "Budget Investments" do
visit budget_investments_path(budget, heading_id: carabanchel.id)
within(".budget-investment", text: "In Carabanchel") do
expect(page).to have_css(".in-favor a[data-confirm]")
expect(page).to have_button count: 1
expect(page).to have_button "Support"
expect(page).to have_css "[type='submit'][data-confirm]"
end
end
@@ -1122,13 +1124,15 @@ describe "Budget Investments" do
salamanca = create(:budget_heading, group: group)
create(:budget_investment, title: "In Carabanchel", heading: carabanchel, voters: [author])
create(:budget_investment, title: "Unsupported in Carabanchel", heading: carabanchel)
create(:budget_investment, title: "In Salamanca", heading: salamanca)
login_as(author)
visit budget_investments_path(budget, heading_id: carabanchel.id)
within(".budget-investment", text: "In Carabanchel") do
expect(page).not_to have_css(".in-favor a[data-confirm]")
within(".budget-investment", text: "Unsupported in Carabanchel") do
expect(page).to have_button "Support"
expect(page).not_to have_css "[data-confirm]"
end
end
@@ -1146,7 +1150,9 @@ describe "Budget Investments" do
visit budget_investments_path(budget, heading_id: another_heading1.id)
within(".budget-investment", text: "Another investment") do
expect(page).to have_css(".in-favor a[data-confirm]")
expect(page).to have_button count: 1
expect(page).to have_button "Support"
expect(page).to have_css "[type='submit'][data-confirm]"
end
end
@@ -1157,7 +1163,8 @@ describe "Budget Investments" do
visit budget_investments_path(budget, heading_id: heading.id)
within("#budget_investment_#{all_city_investment.id}") do
expect(page).not_to have_css(".in-favor a[data-confirm]")
expect(page).to have_button "Support"
expect(page).not_to have_css "[data-confirm]"
end
end
end

View File

@@ -42,7 +42,7 @@ describe "Votes" do
visit budget_investments_path(budget, heading_id: heading.id)
within(".supports") do
click_link "Support this project"
click_button "Support"
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. "\
@@ -63,10 +63,10 @@ describe "Votes" do
visit budget_investment_path(budget, investment)
within(".supports") do
find(".in-favor a").click
expect(page).to have_content "1 support"
click_button "Support"
expect(page).not_to have_selector ".in-favor a"
expect(page).not_to have_button "Support", disabled: :all
expect(page).to have_content "1 support"
end
end
@@ -74,7 +74,7 @@ describe "Votes" do
visit budget_investment_path(budget, investment)
within(".supports") do
find(".in-favor a").click
click_button "Support"
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. "\
@@ -120,7 +120,7 @@ describe "Votes" do
visit budget_investments_path(budget, heading_id: new_york.id)
within("#budget_investment_#{new_york_investment.id}") do
accept_confirm { find(".in-favor a").click }
accept_confirm { click_button "Support" }
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. "\
@@ -130,7 +130,7 @@ describe "Votes" do
visit budget_investments_path(budget, heading_id: san_francisco.id)
within("#budget_investment_#{san_francisco_investment.id}") do
find(".in-favor a").click
click_button "Support"
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. "\
@@ -140,7 +140,7 @@ describe "Votes" do
visit budget_investments_path(budget, heading_id: third_heading.id)
within("#budget_investment_#{third_heading_investment.id}") do
find(".in-favor a").click
click_button "Support"
expect(page).to have_content "You can only support investment projects in 2 districts. "\
"You have already supported investments in"
@@ -160,19 +160,22 @@ describe "Votes" do
scenario "From show" do
visit budget_investment_path(budget, new_york_investment)
accept_confirm { find(".in-favor a").click }
accept_confirm { click_button "Support" }
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. Share it!"
visit budget_investment_path(budget, san_francisco_investment)
find(".in-favor a").click
click_button "Support"
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. Share it!"
visit budget_investment_path(budget, third_heading_investment)
find(".in-favor a").click
click_button "Support"
expect(page).to have_content "You can only support investment projects in 2 districts. "\
"You have already supported investments in"
@@ -189,7 +192,7 @@ describe "Votes" do
scenario "Confirm message shows the right text" do
visit budget_investments_path(budget, heading_id: new_york.id)
find(".in-favor a").click
click_button "Support"
expect(page.driver.send(:find_modal).text).to match "You can only support investments in 2 districts."
end

View File

@@ -277,7 +277,7 @@ describe "Budget Investments" do
expect(page).to have_content(budget_investment.title)
within("#budget-investments") do
find(".js-in-favor a").click
click_button "Support"
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. Share it!"
@@ -302,7 +302,7 @@ describe "Budget Investments" do
expect(page).to have_css "h1", exact_text: budget_investment.title
find(".js-in-favor a").click
click_button "Support"
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. Share it!"
@@ -325,7 +325,7 @@ describe "Budget Investments" do
expect(page).to have_css "h1", exact_text: "Default heading investment"
accept_confirm { find(".js-in-favor a").click }
accept_confirm { click_button "Support" }
expect(page).to have_content "1 support"
expect(page).to have_content "You have already supported this investment project. Share it!"