Allow admins to change reputation modifier (#20766)
* Allow admins to change reputation modifier * locale + rubocop
This commit is contained in:
parent
05d33720db
commit
57c0078bd6
8 changed files with 139 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ module Admin
|
|||
add_org_credits remove_org_credits
|
||||
organization_id identity_id
|
||||
credit_action credit_amount
|
||||
reputation_modifier
|
||||
].freeze
|
||||
|
||||
EMAIL_ALLOWED_PARAMS = %i[
|
||||
|
|
@ -78,6 +79,30 @@ module Admin
|
|||
redirect_to admin_user_path(params[:id])
|
||||
end
|
||||
|
||||
def reputation_modifier
|
||||
@user = User.find(params[:id])
|
||||
reputation_modifier_value = user_params[:reputation_modifier]
|
||||
note_content = if user_params[:new_note].present?
|
||||
"Changed user's reputation modifier to #{reputation_modifier_value}. " \
|
||||
"Reason: #{user_params[:new_note]}"
|
||||
else
|
||||
"Changed user's reputation modifier to #{reputation_modifier_value}."
|
||||
end
|
||||
if @user.update(reputation_modifier: reputation_modifier_value)
|
||||
Note.create(
|
||||
author_id: current_user.id,
|
||||
noteable_id: @user.id,
|
||||
noteable_type: "User",
|
||||
reason: "reputation_modifier_change",
|
||||
content: note_content,
|
||||
)
|
||||
flash[:success] = I18n.t("views.admin.users.reputation.success", reputation_modifier: reputation_modifier_value)
|
||||
else
|
||||
flash[:error] = I18n.t("views.admin.users.reputation.error")
|
||||
end
|
||||
redirect_to admin_user_path(@user)
|
||||
end
|
||||
|
||||
def destroy
|
||||
role = Role.find(params[:role_id])
|
||||
authorize(role, :remove_role?)
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ class User < ApplicationRecord
|
|||
validates :spent_credits_count, presence: true
|
||||
validates :subscribed_to_user_subscriptions_count, presence: true
|
||||
validates :unspent_credits_count, presence: true
|
||||
validates :reputation_modifier, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 5 },
|
||||
presence: true
|
||||
|
||||
# add validators for provider related usernames
|
||||
Authentication::Providers.username_fields.each do |username_field|
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<% if @user.identities.any? %>
|
||||
<li><button type="button" class="c-btn w-100 align-left" data-modal-title="<%= t("views.admin.users.social.heading") %>" data-modal-size="medium" data-modal-content-selector="#remove-social-accounts"><%= t("views.admin.users.profile.options.remove_social") %></button></li>
|
||||
<% end %>
|
||||
<li><button type="button" class="c-btn w-100 align-left" data-modal-title="<%= t("views.admin.users.reputation.heading") %>" data-modal-size="medium" data-modal-content-selector="#change-reputation"><%= t("views.admin.users.reputation.change") %></button></li>
|
||||
<li>
|
||||
<button type="button"
|
||||
class="c-btn c-btn--destructive w-100 align-left"
|
||||
|
|
@ -38,7 +39,7 @@
|
|||
data-form-action="<%= banish_admin_user_path(@user) %>"
|
||||
data-user-name="<%= @user.name %>"
|
||||
data-banishable-user="<%= @banishable_user %>"><%= t("views.admin.users.profile.options.banish") %></button>
|
||||
</li>
|
||||
</li>
|
||||
<li><button type="button" class="c-btn c-btn--destructive w-100 align-left" data-modal-title="<%= t("views.admin.users.delete.heading", user: @user.name) %>" data-modal-size="small" data-modal-content-selector="#delete-user"><%= t("views.admin.users.profile.options.delete") %></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -51,6 +52,7 @@
|
|||
<%= render "admin/users/show/profile/actions/merge" %>
|
||||
<%= render "admin/users/modals/unpublish_modal" %>
|
||||
<%= render "admin/users/show/profile/actions/social_accounts" %>
|
||||
<%= render "admin/users/show/profile/actions/change_reputation" %>
|
||||
<%= render "admin/users/modals/banish_modal" %>
|
||||
<%= render "admin/users/show/profile/actions/delete" %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<div id="change-reputation">
|
||||
<%= form_for(@user, url: reputation_modifier_admin_user_path(@user),
|
||||
html: { class: "flex flex-col gap-4", method: :patch }) do |f| %>
|
||||
<p><%= t("views.admin.users.reputation.desc_html", reputation_modifier: @user.reputation_modifier) %></p>
|
||||
<div class="crayons-field mb-4">
|
||||
<%= f.label :reputation_modifier, t("views.admin.users.reputation.reputation_modifier"), class: "crayons-field__label" %>
|
||||
<%= f.text_field :reputation_modifier, placeholder: @user.reputation_modifier, class: "crayons-textfield", type: "number", inputmode: "numeric", step: "0.01", min: "0", max: 5, aria: { describedby: "reputation_modifier" } %>
|
||||
</div>
|
||||
<div class="crayons-field mb-4">
|
||||
<%= f.label :new_note, t("views.admin.users.reputation.change_note"), class: "crayons-field__label" %>
|
||||
<%= f.text_area :new_note, size: 50, required: true, class: "crayons-textfield", id: "new_note" %>
|
||||
</div>
|
||||
<div>
|
||||
<%= f.button t("views.admin.users.reputation.submit"), class: "c-btn c-btn--primary", type: "submit" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
@ -365,6 +365,15 @@ en:
|
|||
Open: Open
|
||||
Resolved: Resolved
|
||||
Invalid: Invalid
|
||||
reputation:
|
||||
change: Change reputation modifier
|
||||
change_note: Reason for change
|
||||
desc_html: This changes the points awarded to reactions given by the user, increasing or decreasing their impact on article and comment score. The user's current's reputation modifier is <strong>%{reputation_modifier}</strong>.
|
||||
heading: Change reputation modifier
|
||||
reputation_modifier: New reputation modifier
|
||||
submit: Change reputation modifier
|
||||
success: Successfully changed user's reputation modifier to %{reputation_modifier}.
|
||||
error: Failed to change user's reptuation modifier (select between 0 and 5)
|
||||
unpublish_logs:
|
||||
subtitle_html: Unpublished by %{user} on %{time}
|
||||
posts: "Posts:"
|
||||
|
|
|
|||
|
|
@ -363,6 +363,15 @@ fr:
|
|||
Open: Open
|
||||
Resolved: Resolved
|
||||
Invalid: Invalid
|
||||
reputation:
|
||||
change: Changer le modificateur de réputation
|
||||
change_note: Raison du changement
|
||||
desc_html: Cela modifie les points attribués aux réactions données par l'utilisateur, augmentant ou diminuant leur impact sur le score de l'article et du commentaire. Le modificateur de réputation actuel de l'utilisateur est <strong>%{reputation_modifier}</strong>.
|
||||
heading: Changer le modificateur de réputation
|
||||
reputation_modifier: Nouveau modificateur de réputation
|
||||
submit: Changer le modificateur de réputation
|
||||
success: Modification réussie du modificateur de réputation de l'utilisateur en %{reputation_modifier}.
|
||||
error: Échec de la modification du modificateur de réputation de l'utilisateur (sélectionnez entre 0 et 5).
|
||||
unpublish_logs:
|
||||
subtitle_html: Unpublished by %{user} on %{time}
|
||||
posts: "Posts:"
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ namespace :admin do
|
|||
|
||||
member do
|
||||
post "banish"
|
||||
patch "reputation_modifier"
|
||||
post "export_data"
|
||||
post "full_delete"
|
||||
patch "user_status"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "/admin/member_manager/users" do
|
||||
let!(:user) { create(:user) }
|
||||
let!(:admin) { create(:user, :super_admin) }
|
||||
|
||||
before do
|
||||
sign_in(admin)
|
||||
end
|
||||
|
||||
describe "PATCH /admin/member_manager/users/:id/reputation_modifier" do
|
||||
let(:new_reputation_modifier) { 1.5 }
|
||||
let(:note_content) { "Improvement in community engagement" }
|
||||
|
||||
it "updates the user's reputation modifier" do
|
||||
patch reputation_modifier_admin_user_path(user.id), params: {
|
||||
user: {
|
||||
reputation_modifier: new_reputation_modifier,
|
||||
new_note: note_content
|
||||
}
|
||||
}
|
||||
|
||||
user.reload
|
||||
expect(user.reputation_modifier).to eq(new_reputation_modifier)
|
||||
expect(flash[:success]).to be_present
|
||||
end
|
||||
|
||||
it "creates a note with the reason for the change" do
|
||||
expect do
|
||||
patch reputation_modifier_admin_user_path(user.id), params: {
|
||||
user: {
|
||||
reputation_modifier: new_reputation_modifier,
|
||||
new_note: note_content
|
||||
}
|
||||
}
|
||||
end.to change(Note, :count).by(1)
|
||||
|
||||
note = Note.last
|
||||
expect(note.content).to include("Changed user's reputation modifier to #{new_reputation_modifier}")
|
||||
expect(note.content).to include("Reason: #{note_content}")
|
||||
expect(note.reason).to eq("reputation_modifier_change")
|
||||
expect(note.author_id).to eq(admin.id)
|
||||
expect(note.noteable_id).to eq(user.id)
|
||||
end
|
||||
|
||||
it "redirects to the user admin page" do
|
||||
patch reputation_modifier_admin_user_path(user.id), params: {
|
||||
user: {
|
||||
reputation_modifier: new_reputation_modifier,
|
||||
new_note: ""
|
||||
}
|
||||
}
|
||||
|
||||
expect(response).to redirect_to(admin_user_path(user))
|
||||
end
|
||||
|
||||
context "when the update fails" do
|
||||
let(:invalid_reputation_modifier) { "6" }
|
||||
|
||||
it "sets a flash error message" do
|
||||
patch reputation_modifier_admin_user_path(user.id), params: {
|
||||
user: {
|
||||
reputation_modifier: invalid_reputation_modifier,
|
||||
new_note: note_content
|
||||
}
|
||||
}
|
||||
|
||||
expect(flash[:error]).to be_present
|
||||
expect(response).to redirect_to(admin_user_path(user))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue