mirror of
https://github.com/discourse/discourse.git
synced 2025-01-19 07:02:46 +08:00
FEATURE: Replace existing badge owners when using the bulk award feature (#8770)
* FEATURE: Replace existing badge owners when using the bulk award feature * Use ActiveRecord to sanitize title update query, Change replace checkbox text Co-Authored-By: Robin Ward <robin.ward@gmail.com> Co-authored-by: Robin Ward <robin.ward@gmail.com>
This commit is contained in:
parent
db5373a87c
commit
9eb622985a
|
@ -4,6 +4,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
saving: false,
|
saving: false,
|
||||||
|
replaceBadgeOwners: false,
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
massAward() {
|
massAward() {
|
||||||
|
@ -18,6 +19,7 @@ export default Controller.extend({
|
||||||
};
|
};
|
||||||
|
|
||||||
options.data.append("file", file);
|
options.data.append("file", file);
|
||||||
|
options.data.append("replace_badge_owners", this.replaceBadgeOwners);
|
||||||
|
|
||||||
this.set("saving", true);
|
this.set("saving", true);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
<h4>{{I18n 'admin.badges.mass_award.upload_csv'}}</h4>
|
<h4>{{I18n 'admin.badges.mass_award.upload_csv'}}</h4>
|
||||||
<input type='file' id='massAwardCSVUpload' accept='.csv' />
|
<input type='file' id='massAwardCSVUpload' accept='.csv' />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
{{input type="checkbox" checked=replaceBadgeOwners}}
|
||||||
|
{{i18n 'admin.badges.mass_award.replace_owners'}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
{{d-button
|
{{d-button
|
||||||
class="btn-primary"
|
class="btn-primary"
|
||||||
action=(action 'massAward')
|
action=(action 'massAward')
|
||||||
|
|
|
@ -43,6 +43,9 @@ class Admin::BadgesController < Admin::AdminController
|
||||||
badge = Badge.find_by(id: params[:badge_id])
|
badge = Badge.find_by(id: params[:badge_id])
|
||||||
raise Discourse::InvalidParameters if csv_file.try(:tempfile).nil? || badge.nil?
|
raise Discourse::InvalidParameters if csv_file.try(:tempfile).nil? || badge.nil?
|
||||||
|
|
||||||
|
replace_badge_owners = params[:replace_badge_owners] == 'true'
|
||||||
|
BadgeGranter.revoke_all(badge) if replace_badge_owners
|
||||||
|
|
||||||
batch_number = 1
|
batch_number = 1
|
||||||
line_number = 1
|
line_number = 1
|
||||||
batch = []
|
batch = []
|
||||||
|
|
|
@ -104,6 +104,16 @@ class BadgeGranter
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.revoke_all(badge)
|
||||||
|
custom_badge_names = TranslationOverride.where(translation_key: badge.translation_key).pluck(:value)
|
||||||
|
|
||||||
|
users = User.joins(:user_badges).where(user_badges: { badge_id: badge.id }).where(title: badge.name)
|
||||||
|
users = users.or(User.joins(:user_badges).where(title: custom_badge_names)) unless custom_badge_names.empty?
|
||||||
|
users.update_all(title: nil)
|
||||||
|
|
||||||
|
UserBadge.where(badge: badge).delete_all
|
||||||
|
end
|
||||||
|
|
||||||
def self.queue_badge_grant(type, opt)
|
def self.queue_badge_grant(type, opt)
|
||||||
return unless SiteSetting.enable_badges
|
return unless SiteSetting.enable_badges
|
||||||
payload = nil
|
payload = nil
|
||||||
|
|
|
@ -4505,6 +4505,7 @@ en:
|
||||||
upload_csv: Upload a CSV with user emails
|
upload_csv: Upload a CSV with user emails
|
||||||
aborted: Please upload a CSV containing user emails
|
aborted: Please upload a CSV containing user emails
|
||||||
success: Your CSV was received and users will receive their badge shortly.
|
success: Your CSV was received and users will receive their badge shortly.
|
||||||
|
replace_owners: Remove the badge from previous owners
|
||||||
|
|
||||||
emoji:
|
emoji:
|
||||||
title: "Emoji"
|
title: "Emoji"
|
||||||
|
|
|
@ -225,6 +225,39 @@ describe BadgeGranter do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'revoke_all' do
|
||||||
|
it 'deletes every user_badge record associated with that badge' do
|
||||||
|
described_class.grant(badge, user)
|
||||||
|
|
||||||
|
described_class.revoke_all(badge)
|
||||||
|
|
||||||
|
expect(UserBadge.exists?(badge: badge, user: user)).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes titles' do
|
||||||
|
another_title = 'another title'
|
||||||
|
described_class.grant(badge, user)
|
||||||
|
user.update!(title: badge.name)
|
||||||
|
user2 = Fabricate(:user, title: another_title)
|
||||||
|
|
||||||
|
described_class.revoke_all(badge)
|
||||||
|
|
||||||
|
expect(user.reload.title).to be_nil
|
||||||
|
expect(user2.reload.title).to eq(another_title)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes custom badge titles' do
|
||||||
|
custom_badge_title = 'this is a badge title'
|
||||||
|
TranslationOverride.create!(translation_key: badge.translation_key, value: custom_badge_title, locale: 'en_US')
|
||||||
|
described_class.grant(badge, user)
|
||||||
|
user.update!(title: custom_badge_title)
|
||||||
|
|
||||||
|
described_class.revoke_all(badge)
|
||||||
|
|
||||||
|
expect(user.reload.title).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "update_badges" do
|
context "update_badges" do
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
fab!(:liker) { Fabricate(:user) }
|
fab!(:liker) { Fabricate(:user) }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user