FEATURE: remove all invites
https://meta.discourse.org/t/remove-all-invitations-button-for-the-admin-panel/65207
This commit is contained in:
parent
c6b83f4714
commit
e7b9b1312e
|
@ -12,6 +12,7 @@ export default Ember.Controller.extend({
|
|||
canLoadMore: true,
|
||||
invitesLoading: false,
|
||||
reinvitedAll: false,
|
||||
rescindedAll: false,
|
||||
|
||||
init: function() {
|
||||
this._super();
|
||||
|
@ -32,7 +33,7 @@ export default Ember.Controller.extend({
|
|||
|
||||
inviteRedeemed: Em.computed.equal('filter', 'redeemed'),
|
||||
|
||||
showReinviteAllButton: function() {
|
||||
showBulkActionButtons: function() {
|
||||
return (this.get('filter') === "pending" && this.get('model').invites.length > 4 && this.currentUser.get('staff'));
|
||||
}.property('filter'),
|
||||
|
||||
|
@ -86,6 +87,18 @@ export default Ember.Controller.extend({
|
|||
return false;
|
||||
},
|
||||
|
||||
rescindAll() {
|
||||
const self = this;
|
||||
bootbox.confirm(I18n.t("user.invited.rescind_all_confirm"), confirm => {
|
||||
if (confirm) {
|
||||
Invite.rescindAll().then(function() {
|
||||
self.set('rescindedAll', true);
|
||||
self.get('model.invites').clear();
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
reinvite(invite) {
|
||||
invite.reinvite();
|
||||
return false;
|
||||
|
|
|
@ -58,6 +58,10 @@ Invite.reopenClass({
|
|||
|
||||
reinviteAll() {
|
||||
return ajax('/invites/reinvite-all', { type: 'POST' });
|
||||
},
|
||||
|
||||
rescindAll() {
|
||||
return ajax('/invites/rescind-all', { type: 'POST' });
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -19,7 +19,12 @@
|
|||
{{csv-uploader uploading=uploading}}
|
||||
<a href="https://meta.discourse.org/t/sending-bulk-user-invites/16468" target="_blank" style="color:black;">{{fa-icon "question-circle"}}</a>
|
||||
{{/if}}
|
||||
{{#if showReinviteAllButton}}
|
||||
{{#if showBulkActionButtons}}
|
||||
{{#if rescindedAll}}
|
||||
{{i18n 'user.invited.rescinded_all'}}
|
||||
{{else}}
|
||||
{{d-button icon="times" action="rescindAll" class="btn" label="user.invited.rescind_all"}}
|
||||
{{/if}}
|
||||
{{#if reinvitedAll}}
|
||||
{{i18n 'user.invited.reinvited_all'}}
|
||||
{{else}}
|
||||
|
|
|
@ -6,7 +6,7 @@ class InvitesController < ApplicationController
|
|||
skip_before_filter :preload_json, except: [:show]
|
||||
skip_before_filter :redirect_to_login_if_required
|
||||
|
||||
before_filter :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :resend_invite, :resend_all_invites, :upload_csv]
|
||||
before_filter :ensure_logged_in, only: [:destroy, :create, :create_invite_link, :rescind_all_invites, :resend_invite, :resend_all_invites, :upload_csv]
|
||||
before_filter :ensure_new_registrations_allowed, only: [:show, :perform_accept_invitation, :redeem_disposable_invite]
|
||||
before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation, :redeem_disposable_invite]
|
||||
|
||||
|
@ -150,6 +150,13 @@ class InvitesController < ApplicationController
|
|||
render nothing: true
|
||||
end
|
||||
|
||||
def rescind_all_invites
|
||||
guardian.ensure_can_rescind_all_invites!(current_user)
|
||||
|
||||
Invite.rescind_all_invites_from(current_user)
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
def resend_invite
|
||||
params.require(:email)
|
||||
RateLimiter.new(current_user, "resend-invite-per-hour", 10, 1.hour).performed!
|
||||
|
|
|
@ -256,6 +256,12 @@ class Invite < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.rescind_all_invites_from(user)
|
||||
Invite.where('invites.user_id IS NULL AND invites.email IS NOT NULL AND invited_by_id = ?', user.id).find_each do |invite|
|
||||
invite.trash!(user) unless invite.blank?
|
||||
end
|
||||
end
|
||||
|
||||
def limit_invites_per_day
|
||||
RateLimiter.new(invited_by, "invites-per-day", SiteSetting.max_invites_per_day, 1.day.to_i)
|
||||
end
|
||||
|
|
|
@ -836,6 +836,9 @@ en:
|
|||
expired: "This invite has expired."
|
||||
rescind: "Remove"
|
||||
rescinded: "Invite removed"
|
||||
rescind_all: "Remove all Invites"
|
||||
rescinded_all: "All Invites removed!"
|
||||
rescind_all_confirm: "Are you sure you want to remove all invites?"
|
||||
reinvite: "Resend Invite"
|
||||
reinvite_all: "Resend all Invites"
|
||||
reinvite_all_confirm: "Are you sure you want to resend all invites?"
|
||||
|
|
|
@ -646,6 +646,7 @@ Discourse::Application.routes.draw do
|
|||
|
||||
resources :invites
|
||||
post "invites/upload_csv" => "invites#upload_csv"
|
||||
post "invites/rescind-all" => "invites#rescind_all_invites"
|
||||
post "invites/reinvite" => "invites#resend_invite"
|
||||
post "invites/reinvite-all" => "invites#resend_all_invites"
|
||||
post "invites/link" => "invites#create_invite_link"
|
||||
|
|
|
@ -269,6 +269,10 @@ class Guardian
|
|||
user.staff?
|
||||
end
|
||||
|
||||
def can_rescind_all_invites?(user)
|
||||
user.staff?
|
||||
end
|
||||
|
||||
def can_see_private_messages?(user_id)
|
||||
is_admin? || (authenticated? && @user.id == user_id)
|
||||
end
|
||||
|
|
|
@ -484,4 +484,16 @@ describe Invite do
|
|||
|
||||
end
|
||||
|
||||
describe '.rescind_all_invites_from' do
|
||||
it 'removes all invites sent by a user' do
|
||||
user = Fabricate(:user)
|
||||
invite_1 = Fabricate(:invite, invited_by: user)
|
||||
invite_2 = Fabricate(:invite, invited_by: user)
|
||||
Invite.rescind_all_invites_from(user)
|
||||
invite_1.reload
|
||||
invite_2.reload
|
||||
expect(invite_1.deleted_at).to be_present
|
||||
expect(invite_2.deleted_at).to be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue