Skip to content

Commit

Permalink
Minor fixes and improvements for frontend voting (#19)
Browse files Browse the repository at this point in the history
* change basic copies

* namespace css

* add link "change my vote"

* change opacity method

* add tests

* add check settings for abstain

* fix cell test

---------

Co-authored-by: Anna Topalidi <[email protected]>
  • Loading branch information
microstudi and antopalidi authored Oct 27, 2023
1 parent fd679a0 commit ef5770a
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
<h4 class="heading4 vote-title"><%= t("decidim.decidim_awesome.proposal_m.modal.title") %></h4>
<% if voted_for_any? %>
<p class="text-center">
<%= action_authorized_link_to :unvote,
"👉 #{t('decidim.decidim_awesome.proposal_m.change_vote')}",
proposal_vote_path(current_vote&.weight),
resource: proposal,
remote: true,
method: :delete,
id: "change-vote",
class: "change-vote-button" %>
<% end %>
</p>

<div class="flex--sbc">
<%= vote_block_for(proposal, 3, "green") %>
<%= vote_block_for(proposal, 2, "yellow") %>
<%= vote_block_for(proposal, 1, "red") %>
</div>

<%= action_authorized_link_to :vote,
t("decidim.decidim_awesome.proposal_m.abstain"),
proposal_vote_path(0),
resource: proposal,
remote: true,
method: voted_for?(0) ? :delete : :post,
class: "button expanded abstain-button small #{opacity_class_for(0)}" %>
<% if current_component.settings.proposal_vote_abstain %>
<%= action_authorized_link_to :vote,
t("decidim.decidim_awesome.proposal_m.abstain"),
proposal_vote_path(0),
resource: proposal,
remote: true,
method: :post,
class: "button expanded abstain-button small #{opacity_class_for(0)}" %>
<% end %>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
proposal_vote_path(weight),
resource: proposal,
remote: true,
method: voted_for?(weight) ? :delete : :post,
method: :post,
class: "rectangle voting-block #{color} #{opacity_class_for(weight)} #{'voted' if voted_for?(weight)}" do %>
<%= icon "thumb-up" %>
<% end %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ def proposal_vote_path(weight)
proposal_proposal_vote_path(proposal_id: proposal.id, from_proposals_list: from_proposals_list, weight: weight)
end

def opacity_class_for(option)
!voted_for_any? || voted_for?(option) ? "fully-opaque" : "semi-opaque"
def opacity_class_for(weight)
opacity = !voted_for_any? || voted_for?(weight) ? "fully-opaque" : "semi-opaque"
clickable = voted_for_any? ? "non-clickable" : ""

[opacity, clickable].reject(&:empty?).join(" ")
end

def voted_for_any?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.voting-three-flag,
.button--vote-button {
.voting-three-flags {
$rectangle-width: 3rem;
$green-color: #4caf50;
$yellow-color: #ffc107;
Expand Down Expand Up @@ -61,6 +60,10 @@
pointer-events: none;
}

.non-clickable {
pointer-events: none;
}

.vote-block,
.vote-link {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
<%= cell("decidim/decidim_awesome/voting/three_flags_proposal", proposal, from_proposals_list: true) %>
<div class="voting-three-flags">
<%= cell("decidim/decidim_awesome/voting/three_flags_proposal", proposal, from_proposals_list: true) %>
</div>
6 changes: 4 additions & 2 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ en:
awesome_voting_manifest_options:
default: Simple vote (default)
three_flags: Traffic lights using flags
proposal_vote_abstain: Allow abstentions for any particular vote.
proposal_vote_instructions: Voting instructions (modal window)
proposal_vote_abstain: Add an abstain option
proposal_vote_instructions: Support instructions/help (dissmissable modal
window)
decidim_awesome:
admin:
admin_accountability:
Expand Down Expand Up @@ -492,6 +493,7 @@ en:
view_proposal: View proposal
proposal_m:
abstain: Abstain
change_vote: Change my vote
modal:
message: Your vote will be considered final on %{date}. You can change it
until then
Expand Down
10 changes: 5 additions & 5 deletions spec/cells/voting/three_flags_proposal_cell_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ module Voting
create(:awesome_vote_weight, vote: create(:proposal_vote, proposal: proposal, author: user), weight: 1)
end

it "returns 'fully-opaque' for the weight the user has voted for" do
expect(subject.opacity_class_for(1)).to eq("fully-opaque")
it "returns 'fully-opaque non-clickable' for the weight the user has voted for" do
expect(subject.opacity_class_for(1)).to eq("fully-opaque non-clickable")
end

it "returns 'semi-opaque' for the weights the user has not voted for" do
expect(subject.opacity_class_for(2)).to eq("semi-opaque")
expect(subject.opacity_class_for(3)).to eq("semi-opaque")
it "returns 'semi-opaque non-clickable' for the weights the user has not voted for" do
expect(subject.opacity_class_for(2)).to eq("semi-opaque non-clickable")
expect(subject.opacity_class_for(3)).to eq("semi-opaque non-clickable")
end
end

Expand Down
91 changes: 90 additions & 1 deletion spec/system/three_flags_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
include_context "with a component"
let!(:organization) { create :organization }
let(:manifest) { :three_flags }
let!(:component) { create :proposal_component, :with_votes_enabled, organization: organization, settings: { awesome_voting_manifest: manifest } }
let!(:component) { create :proposal_component, :with_votes_enabled, organization: organization, settings: { awesome_voting_manifest: manifest, proposal_vote_abstain: proposal_vote_abstain } }
let!(:proposals) { create_list(:proposal, 3, component: component) }
let!(:proposal) { Decidim::Proposals::Proposal.find_by(component: component) }
let(:proposal_title) { translated(proposal.title) }
let(:user) { create :user, :confirmed, organization: organization }
let(:proposal_vote_abstain) { true }

def click_to_vote
within "#proposal-#{proposal.id}-vote-button" do
Expand Down Expand Up @@ -68,6 +69,94 @@ def click_to_vote
expect(page).to have_selector("p.vote-count[data-id=\"#{proposal.id}\"][data-weight=\"3\"]", text: "1")
end
end

context "when proposal has no votes" do
it "shows 0 votes" do
click_to_vote
expect(page).to have_selector("p.vote-count[data-id=\"#{proposal.id}\"][data-weight=\"1\"]", text: "0")
expect(page).to have_selector("p.vote-count[data-id=\"#{proposal.id}\"][data-weight=\"2\"]", text: "0")
expect(page).to have_selector("p.vote-count[data-id=\"#{proposal.id}\"][data-weight=\"3\"]", text: "0")
end
end

context "when user votes" do
before do
click_to_vote
end

context "when user didn't vote" do
it "doesn't show link 'Change my vote'" do
expect(page).not_to have_content("Change my vote")
end

it "allows the user to click on the voting button, with all voting blocks having no opacity" do
expect(page).to have_selector(".abstain-button:not(.non-clickable)")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-1 a:not(.non-clickable)")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-2 a:not(.non-clickable)")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-3 a:not(.non-clickable)")
end
end

context "when user voted" do
before do
find("#vote-proposal-#{proposal.id}-3 a").click
end

it "shows vote" do
expect(page).to have_selector("p.vote-count[data-id=\"#{proposal.id}\"][data-weight=\"3\"]", text: "1")
end

it "shows link 'Change my vote'" do
expect(page).to have_content("Change my vote")
end

it "can delete vote" do
click_link "Change my vote"
sleep 1
expect(page).to have_selector("p.vote-count[data-id=\"#{proposal.id}\"][data-weight=\"3\"]", text: "0")
end

it "does not allow the user to click on the voting button, with blocks without vote having opacity" do
expect(page).to have_selector(".abstain-button.non-clickable")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-1 a.non-clickable")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-2 a.non-clickable")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-3 a.non-clickable")

expect(page).to have_selector(".abstain-button.semi-opaque")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-1 a.semi-opaque")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-2 a.semi-opaque")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-3 a.fully-opaque")
end

context "when abstain option enabled" do
before do
click_link "Abstain"
end

it "all voting blocks have opacity" do
expect(page).to have_selector(".abstain-button.fully-opaque")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-1 a.fully-opaque")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-2 a.fully-opaque")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-3 a.fully-opaque")
end

it "all voting blocks are non-clickable" do
expect(page).to have_selector(".abstain-button.non-clickable")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-1 a.non-clickable")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-2 a.non-clickable")
expect(page).to have_selector("#vote-proposal-#{proposal.id}-3 a.non-clickable")
end
end

context "when abstain option disabled" do
let(:proposal_vote_abstain) { false }

it "does not show abstain option" do
expect(page).not_to have_content("Abstain")
end
end
end
end
end
end
end

0 comments on commit ef5770a

Please sign in to comment.