mirror of
https://github.com/discourse/discourse.git
synced 2025-09-06 10:50:21 +08:00
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
9 changed files with 58 additions and 3 deletions
|
@ -12,6 +12,7 @@ export default Ember.Controller.extend({
|
||||||
canLoadMore: true,
|
canLoadMore: true,
|
||||||
invitesLoading: false,
|
invitesLoading: false,
|
||||||
reinvitedAll: false,
|
reinvitedAll: false,
|
||||||
|
rescindedAll: false,
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
this._super();
|
this._super();
|
||||||
|
@ -32,7 +33,7 @@ export default Ember.Controller.extend({
|
||||||
|
|
||||||
inviteRedeemed: Em.computed.equal('filter', 'redeemed'),
|
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'));
|
return (this.get('filter') === "pending" && this.get('model').invites.length > 4 && this.currentUser.get('staff'));
|
||||||
}.property('filter'),
|
}.property('filter'),
|
||||||
|
|
||||||
|
@ -86,6 +87,18 @@ export default Ember.Controller.extend({
|
||||||
return false;
|
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) {
|
reinvite(invite) {
|
||||||
invite.reinvite();
|
invite.reinvite();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -58,6 +58,10 @@ Invite.reopenClass({
|
||||||
|
|
||||||
reinviteAll() {
|
reinviteAll() {
|
||||||
return ajax('/invites/reinvite-all', { type: 'POST' });
|
return ajax('/invites/reinvite-all', { type: 'POST' });
|
||||||
|
},
|
||||||
|
|
||||||
|
rescindAll() {
|
||||||
|
return ajax('/invites/rescind-all', { type: 'POST' });
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,12 @@
|
||||||
{{csv-uploader uploading=uploading}}
|
{{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>
|
<a href="https://meta.discourse.org/t/sending-bulk-user-invites/16468" target="_blank" style="color:black;">{{fa-icon "question-circle"}}</a>
|
||||||
{{/if}}
|
{{/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}}
|
{{#if reinvitedAll}}
|
||||||
{{i18n 'user.invited.reinvited_all'}}
|
{{i18n 'user.invited.reinvited_all'}}
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -6,7 +6,7 @@ class InvitesController < ApplicationController
|
||||||
skip_before_filter :preload_json, except: [:show]
|
skip_before_filter :preload_json, except: [:show]
|
||||||
skip_before_filter :redirect_to_login_if_required
|
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_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]
|
before_filter :ensure_not_logged_in, only: [:show, :perform_accept_invitation, :redeem_disposable_invite]
|
||||||
|
|
||||||
|
@ -150,6 +150,13 @@ class InvitesController < ApplicationController
|
||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
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
|
def resend_invite
|
||||||
params.require(:email)
|
params.require(:email)
|
||||||
RateLimiter.new(current_user, "resend-invite-per-hour", 10, 1.hour).performed!
|
RateLimiter.new(current_user, "resend-invite-per-hour", 10, 1.hour).performed!
|
||||||
|
|
|
@ -256,6 +256,12 @@ class Invite < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
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
|
def limit_invites_per_day
|
||||||
RateLimiter.new(invited_by, "invites-per-day", SiteSetting.max_invites_per_day, 1.day.to_i)
|
RateLimiter.new(invited_by, "invites-per-day", SiteSetting.max_invites_per_day, 1.day.to_i)
|
||||||
end
|
end
|
||||||
|
|
|
@ -836,6 +836,9 @@ en:
|
||||||
expired: "This invite has expired."
|
expired: "This invite has expired."
|
||||||
rescind: "Remove"
|
rescind: "Remove"
|
||||||
rescinded: "Invite removed"
|
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: "Resend Invite"
|
||||||
reinvite_all: "Resend all Invites"
|
reinvite_all: "Resend all Invites"
|
||||||
reinvite_all_confirm: "Are you sure you want to 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
|
resources :invites
|
||||||
post "invites/upload_csv" => "invites#upload_csv"
|
post "invites/upload_csv" => "invites#upload_csv"
|
||||||
|
post "invites/rescind-all" => "invites#rescind_all_invites"
|
||||||
post "invites/reinvite" => "invites#resend_invite"
|
post "invites/reinvite" => "invites#resend_invite"
|
||||||
post "invites/reinvite-all" => "invites#resend_all_invites"
|
post "invites/reinvite-all" => "invites#resend_all_invites"
|
||||||
post "invites/link" => "invites#create_invite_link"
|
post "invites/link" => "invites#create_invite_link"
|
||||||
|
|
|
@ -269,6 +269,10 @@ class Guardian
|
||||||
user.staff?
|
user.staff?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_rescind_all_invites?(user)
|
||||||
|
user.staff?
|
||||||
|
end
|
||||||
|
|
||||||
def can_see_private_messages?(user_id)
|
def can_see_private_messages?(user_id)
|
||||||
is_admin? || (authenticated? && @user.id == user_id)
|
is_admin? || (authenticated? && @user.id == user_id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -484,4 +484,16 @@ describe Invite do
|
||||||
|
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue