Merge pull request #5740 from consuldemocracy/button_confirmations

Use buttons for actions requiring confirmation
This commit is contained in:
Javi Martín
2024-11-08 14:11:35 +01:00
committed by GitHub
29 changed files with 195 additions and 72 deletions

View File

@@ -56,6 +56,7 @@
@import "sdg_management/**/*";
@import "shared/**/*";
@import "subscriptions";
@import "users/**/*";
@import "widgets/**/*";
@import "custom";

View File

@@ -442,6 +442,14 @@
.button {
font-weight: bold;
}
button {
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
.community-poll {

View File

@@ -0,0 +1,15 @@
.debate-show .mark-featured-action {
display: inline;
&::before {
@include vertical-separator;
}
form {
display: inline;
}
button {
@include link;
}
}

View File

@@ -3,7 +3,7 @@
margin-top: calc(#{$line-height} / 3);
}
a:first-of-type {
a {
word-wrap: break-word;
.document-metadata {
@@ -18,4 +18,8 @@
}
}
}
button {
cursor: pointer;
}
}

View File

@@ -1245,7 +1245,7 @@ table {
}
.button {
margin: 0;
margin-bottom: 0;
}
}
@@ -1543,8 +1543,13 @@ table {
}
}
.delete-comment-form {
display: inline;
}
.delete-comment {
@include has-fa-icon(trash-alt, regular);
cursor: pointer;
&:not(:hover):not(:active) {
color: $delete;
@@ -1943,10 +1948,18 @@ table {
.hide-recommendations {
color: $text-light;
cursor: pointer;
font-size: $small-font-size;
line-height: inherit;
position: absolute;
right: 12px;
top: -18px;
z-index: 2;
&:focus,
&:hover {
@include anchor-color-hover;
}
}
// 20. Documents

View File

@@ -0,0 +1,3 @@
.user-budget-investment-table-actions {
@include flex-with-gap($line-height * 0.25);
}

View File

@@ -0,0 +1,17 @@
<div class="mark-featured-action">
<% if debate.featured? %>
<%= button_to t("admin.actions.unmark_featured").capitalize,
unmark_featured_debate_path(debate),
method: :put,
data: { confirm: t("admin.actions.confirm_action",
action: t("admin.actions.unmark_featured"),
name: debate.title) } %>
<% else %>
<%= button_to t("admin.actions.mark_featured").capitalize,
mark_featured_debate_path(debate),
method: :put,
data: { confirm: t("admin.actions.confirm_action",
action: t("admin.actions.mark_featured"),
name: debate.title) } %>
<% end %>
</div>

View File

@@ -0,0 +1,12 @@
class Debates::MarkFeaturedActionComponent < ApplicationComponent
attr_reader :debate
use_helpers :can?
def initialize(debate)
@debate = debate
end
def render
can? :mark_featured, debate
end
end

View File

@@ -8,10 +8,10 @@
<% end %>
<% if show_destroy_link? && can?(:destroy, document) %>
<%= link_to t("documents.buttons.destroy_document"),
document,
method: :delete,
data: { confirm: t("documents.actions.destroy.confirm") },
class: "delete" %>
<%= button_to t("documents.buttons.destroy_document"),
document,
method: :delete,
data: { confirm: t("documents.actions.destroy.confirm") },
class: "delete" %>
<% end %>
</div>

View File

@@ -0,0 +1,9 @@
<div class="user-budget-investment-table-actions">
<% if can? :update, investment %>
<%= edit_link %>
<% end %>
<% if can? :destroy, investment %>
<%= destroy_button %>
<% end %>
</div>

View File

@@ -0,0 +1,30 @@
class Users::BudgetInvestmentTableActionsComponent < ApplicationComponent
attr_reader :investment
use_helpers :can?
def initialize(investment)
@investment = investment
end
private
def edit_link
link_to t("shared.edit"),
edit_budget_investment_path(investment.budget, investment),
"aria-label": action_label(t("shared.edit")),
class: "button hollow"
end
def destroy_button
button_to t("shared.delete"),
budget_investment_path(investment.budget, investment),
method: :delete,
"aria-label": action_label(t("shared.delete")),
class: "button hollow alert",
data: { confirm: t("users.show.delete_alert") }
end
def action_label(action_text)
t("shared.actions.label", action: action_text, name: investment.title)
end
end

View File

@@ -5,10 +5,10 @@
<% if can?(:hide, comment) || can?(:hide, comment.user) %>
<% if comment.author == current_user %>
<span class="divider">&nbsp;&bull;&nbsp;</span>
<%= link_to t("comments.actions.delete"),
hide_comment_path(comment),
method: :put, remote: true, class: "delete-comment",
data: { confirm: t("comments.actions.confirm_delete") } %>
<%= button_to t("comments.actions.delete"),
hide_comment_path(comment),
method: :put, remote: true, class: "delete-comment", form_class: "delete-comment-form",
data: { confirm: t("comments.actions.confirm_delete") } %>
<% else %>
<%= render Shared::ModerationActionsComponent.new(comment) %>
<% end %>

View File

@@ -27,10 +27,10 @@
<% end %>
<p class="help-text"><%= t("dashboard.polls.poll.show_results_help") %></p>
<%= link_to t("dashboard.polls.poll.delete"),
proposal_dashboard_poll_path(proposal, poll),
method: :delete,
"data-confirm": t("dashboard.polls.poll.alert_notice"),
class: "delete" %>
<%= button_to t("dashboard.polls.poll.delete"),
proposal_dashboard_poll_path(proposal, poll),
method: :delete,
"data-confirm": t("dashboard.polls.poll.alert_notice"),
class: "delete" %>
</div>
</div>

View File

@@ -1,18 +1,2 @@
<%= render Shared::ModerationActionsComponent.new(debate) %>
<% if can? :mark_featured, debate %>
&nbsp;|&nbsp;
<% if debate.featured? %>
<%= link_to t("admin.actions.unmark_featured").capitalize, unmark_featured_debate_path(debate),
method: :put,
data: { confirm: t("admin.actions.confirm_action",
action: t("admin.actions.unmark_featured"),
name: debate.title) } %>
<% else %>
<%= link_to t("admin.actions.mark_featured").capitalize, mark_featured_debate_path(debate),
method: :put,
data: { confirm: t("admin.actions.confirm_action",
action: t("admin.actions.mark_featured"),
name: debate.title) } %>
<% end %>
<% end %>
<%= render Debates::MarkFeaturedActionComponent.new(debate) %>

View File

@@ -5,5 +5,5 @@
<%= t("management.users.erase_warning") %>
</div>
<%= link_to t("management.users.erase_submit"), erase_management_users_path, method: :delete, class: "button hollow alert", data: { confirm: t("management.users.erase_account_confirm") } %>
<%= button_to t("management.users.erase_submit"), erase_management_users_path, method: :delete, class: "button hollow alert", data: { confirm: t("management.users.erase_account_confirm") } %>
</div>

View File

@@ -5,13 +5,13 @@
</div>
<div id="recommendations" data-toggler=".hide">
<%= link_to disable_recommendations_path, title: t("shared.recommended_index.hide"),
class: "float-right-medium small hide-recommendations",
data: {
toggle: "recommendations",
confirm: t("#{namespace}.index.recommendations.disable")
},
method: :put do %>
<%= button_to disable_recommendations_path, title: t("shared.recommended_index.hide"),
class: "hide-recommendations",
data: {
toggle: "recommendations",
confirm: t("#{namespace}.index.recommendations.disable")
},
method: :put do %>
<span class="icon-x"></span>
<span class="show-for-sr"><%= t("shared.recommended_index.hide") %></span>
<% end %>

View File

@@ -3,14 +3,6 @@
<%= link_to budget_investment.title, budget_investment_path(budget_investment.budget, budget_investment) %>
</td>
<td>
<% if can? :update, budget_investment %>
<%= link_to t("shared.edit"), edit_budget_investment_path(budget_investment.budget, budget_investment),
class: "button hollow" %>
<% end %>
<% if can? :destroy, budget_investment %>
<%= link_to t("shared.delete"), budget_investment_path(budget_investment.budget, budget_investment),
method: :delete, class: "button hollow alert",
data: { confirm: t("users.show.delete_alert") } %>
<% end %>
<%= render Users::BudgetInvestmentTableActionsComponent.new(budget_investment) %>
</td>
</tr>

View File

@@ -644,6 +644,8 @@ en:
show:
back: "Go back to my content"
shared:
actions:
label: "%{action} %{name}"
edit: "Edit"
filter: "Filter"
save: "Save"

View File

@@ -644,6 +644,8 @@ es:
show:
back: "Volver a mi contenido"
shared:
actions:
label: "%{action} %{name}"
edit: "Editar"
filter: "Filtrar"
save: "Guardar"

View File

@@ -0,0 +1,31 @@
require "rails_helper"
describe Users::BudgetInvestmentTableActionsComponent do
let(:user) { create(:user, :level_two) }
let(:budget) { create(:budget, :accepting) }
let(:investment) { create(:budget_investment, budget: budget, author: user, title: "User investment") }
describe "#edit_link" do
it "generates an aria-label attribute" do
sign_in(user)
render_inline Users::BudgetInvestmentTableActionsComponent.new(investment)
expect(page).to have_link count: 1
expect(page).to have_link "Edit"
expect(page).to have_css "a[aria-label='Edit User investment']"
end
end
describe "#destroy_button" do
it "generates an aria-label attribute" do
sign_in(user)
render_inline Users::BudgetInvestmentTableActionsComponent.new(investment)
expect(page).to have_button count: 1
expect(page).to have_button "Delete"
expect(page).to have_css "button[aria-label='Delete User investment']"
end
end
end

View File

@@ -25,27 +25,27 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path,
scenario "Should not be able when no user logged in" do
visit send(documentable_path, arguments)
expect(page).not_to have_link("Delete document")
expect(page).not_to have_button "Delete document"
end
scenario "Should be able when documentable author is logged in" do
login_as documentable.author
visit send(documentable_path, arguments)
expect(page).to have_link("Delete document")
expect(page).to have_button "Delete document"
end
scenario "Administrators cannot destroy documentables they have not authored", :admin do
visit send(documentable_path, arguments)
expect(page).not_to have_link("Delete document")
expect(page).not_to have_button "Delete document"
end
scenario "Users cannot destroy documentables they have not authored" do
login_as(create(:user))
visit send(documentable_path, arguments)
expect(page).not_to have_link("Delete document")
expect(page).not_to have_button "Delete document"
end
end
@@ -93,7 +93,7 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path,
visit send(documentable_path, arguments)
within "#document_#{document.id}" do
accept_confirm { click_link "Delete document" }
accept_confirm { click_button "Delete document" }
end
expect(page).to have_content "Document was deleted successfully."
@@ -105,7 +105,7 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path,
visit send(documentable_path, arguments)
within "#document_#{document.id}" do
accept_confirm { click_link "Delete document" }
accept_confirm { click_button "Delete document" }
end
expect(page).not_to have_content "Documents (0)"
@@ -117,7 +117,7 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path,
visit send(documentable_path, arguments)
within "#document_#{document.id}" do
accept_confirm { click_link "Delete document" }
accept_confirm { click_button "Delete document" }
end
within "##{ActionView::RecordIdentifier.dom_id(documentable)}" do

View File

@@ -1170,7 +1170,7 @@ describe "Budget Investments" do
within("#budget_investment_#{investment1.id}") do
expect(page).to have_content(investment1.title)
accept_confirm { click_link("Delete") }
accept_confirm { click_button "Delete" }
end
expect(page).to have_content "Investment project deleted successfully"

View File

@@ -336,16 +336,16 @@ describe "Comments" do
visit polymorphic_path(resource)
accept_confirm("Are you sure? This action will delete this comment. You can't undo this action.") do
within(".comment-body", text: "This was a mistake") { click_link "Delete comment" }
within(".comment-body", text: "This was a mistake") { click_button "Delete comment" }
end
expect(page).not_to have_content "This was a mistake"
expect(page).not_to have_link "Delete comment"
expect(page).not_to have_button "Delete comment"
refresh
expect(page).not_to have_content "This was a mistake"
expect(page).not_to have_link "Delete comment"
expect(page).not_to have_button "Delete comment"
logout
login_as(admin)
@@ -363,7 +363,7 @@ describe "Comments" do
visit polymorphic_path(resource)
accept_confirm("Are you sure? This action will delete this comment. You can't undo this action.") do
within(".comment-body", text: "Wrong comment") { click_link "Delete comment" }
within(".comment-body", text: "Wrong comment") { click_button "Delete comment" }
end
within "#comments > .comment-list > li", text: "Right reply" do

View File

@@ -199,7 +199,7 @@ describe "Polls" do
visit proposal_dashboard_polls_path(proposal)
within("#poll_#{poll.id}") do
accept_confirm { click_link "Delete survey" }
accept_confirm { click_button "Delete survey" }
end
expect(page).to have_content("Survey deleted successfully")
@@ -214,7 +214,7 @@ describe "Polls" do
visit proposal_dashboard_polls_path(proposal)
within("#poll_#{poll.id}") do
accept_confirm { click_link "Delete survey" }
accept_confirm { click_button "Delete survey" }
end
expect(page).to have_content("You cannot destroy a survey that has responses")

View File

@@ -521,7 +521,7 @@ describe "Debates" do
expect(page).to have_content("Medium")
expect(page).to have_css(".recommendation", count: 3)
accept_confirm { click_link "Hide recommendations" }
accept_confirm { click_button "Hide recommendations" }
end
expect(page).not_to have_link("recommendations")
@@ -748,7 +748,7 @@ describe "Debates" do
end
click_link debate.title
accept_confirm("Are you sure? Featured") { click_link "Featured" }
accept_confirm("Are you sure? Featured") { click_button "Featured" }
within("#debates") do
expect(page).to have_content "FEATURED"
@@ -760,7 +760,7 @@ describe "Debates" do
click_link debate.title
end
accept_confirm("Are you sure? Unmark featured") { click_link "Unmark featured" }
accept_confirm("Are you sure? Unmark featured") { click_button "Unmark featured" }
within("#debates") do
expect(page).not_to have_content "FEATURED"

View File

@@ -82,7 +82,7 @@ describe "Users" do
expect(page).to have_content "This user can participate in the website with the following permissions"
click_link "Delete user"
accept_confirm { click_link "Delete account" }
accept_confirm { click_button "Delete account" }
expect(page).to have_content "User account deleted."

View File

@@ -937,7 +937,7 @@ describe "Proposals" do
expect(page).to have_content("Medium")
expect(page).to have_css(".recommendation", count: 3)
accept_confirm { click_link "Hide recommendations" }
accept_confirm { click_button "Hide recommendations" }
end
expect(page).not_to have_link("recommendations")

View File

@@ -131,12 +131,12 @@ describe "Users" do
expect(page).to have_link budget_investment.title
within("#budget_investment_#{budget_investment.id}") do
dismiss_confirm { click_link "Delete" }
dismiss_confirm { click_button "Delete" }
end
expect(page).to have_link budget_investment.title
within("#budget_investment_#{budget_investment.id}") do
accept_confirm { click_link "Delete" }
accept_confirm { click_button "Delete" }
end
expect(page).not_to have_link budget_investment.title
end

View File

@@ -410,7 +410,7 @@ describe "Valuation budget investments" do
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Edit dossier"
accept_confirm { find_field("budget_investment[valuation_finished]").click }
accept_confirm { check "Valuation finished" }
click_button "Save changes"
expect(page).to have_content "Dossier updated"