mirror of
https://github.com/discourse/discourse.git
synced 2025-01-31 17:47:01 +08:00
UX: Nicer selection of suspend duration
This commit is contained in:
parent
677b016387
commit
6bce3004d9
|
@ -3,34 +3,32 @@ import computed from 'ember-addons/ember-computed-decorators';
|
|||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend(ModalFunctionality, {
|
||||
duration: null,
|
||||
suspendUntil: null,
|
||||
reason: null,
|
||||
message: null,
|
||||
loading: false,
|
||||
|
||||
onShow() {
|
||||
this.setProperties({
|
||||
duration: null,
|
||||
suspendUntil: null,
|
||||
reason: null,
|
||||
message: null,
|
||||
loading: false
|
||||
});
|
||||
},
|
||||
|
||||
@computed('reason', 'loading')
|
||||
submitDisabled(reason, loading) {
|
||||
return (loading || !reason || reason.length < 1);
|
||||
@computed('suspendUntil', 'reason', 'loading')
|
||||
submitDisabled(suspendUntil, reason, loading) {
|
||||
return (loading || Ember.isEmpty(suspendUntil) || !reason || reason.length < 1);
|
||||
},
|
||||
|
||||
actions: {
|
||||
suspend() {
|
||||
if (this.get('submitDisabled')) { return; }
|
||||
|
||||
let duration = parseInt(this.get('duration'), 10);
|
||||
if (duration > 0) {
|
||||
this.set('loading', true);
|
||||
this.get('model').suspend({
|
||||
duration,
|
||||
suspend_until: this.get('suspendUntil'),
|
||||
reason: this.get('reason'),
|
||||
message: this.get('message')
|
||||
}).then(() => {
|
||||
|
@ -38,6 +36,5 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
|||
}).catch(popupAjaxError).finally(() => this.set('loading', false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{{#d-modal-body title="admin.user.suspend_modal_title"}}
|
||||
<div class='duration-controls'>
|
||||
<div class='until-controls'>
|
||||
<label>
|
||||
{{i18n 'admin.user.suspend_duration'}}
|
||||
{{text-field value=duration maxlength="5" autofocus="autofocus" class="suspend-duration"}}
|
||||
{{i18n 'admin.user.suspend_duration_units'}}
|
||||
{{auto-update-input
|
||||
class="suspend-until"
|
||||
label="admin.user.suspend_duration"
|
||||
input=suspendUntil}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -298,7 +298,12 @@
|
|||
|
||||
<div class="user-suspended display-row {{if model.isSuspended 'highlight-danger'}}">
|
||||
<div class='field'>{{i18n 'admin.user.suspended'}}</div>
|
||||
<div class='value'>{{i18n-yes-no model.isSuspended}}</div>
|
||||
<div class='value'>
|
||||
{{i18n-yes-no model.isSuspended}}
|
||||
{{#if model.isSuspended}}
|
||||
{{i18n "admin.user.suspended_until" until=model.suspendedTillDate}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='controls'>
|
||||
{{#if model.isSuspended}}
|
||||
{{d-button
|
||||
|
@ -306,7 +311,6 @@
|
|||
action=(action "unsuspend")
|
||||
icon="ban"
|
||||
label="admin.user.unsuspend"}}
|
||||
{{suspendDuration}}
|
||||
{{i18n 'admin.user.suspended_explanation'}}
|
||||
{{else}}
|
||||
{{#if model.canSuspend}}
|
||||
|
|
|
@ -124,7 +124,7 @@ export default Ember.Component.extend(bufferedRender({
|
|||
if (val && val.length && castInteger) {
|
||||
val = parseInt(val, 10);
|
||||
}
|
||||
this.set('value', val);
|
||||
Ember.run(() => this.set('value', val));
|
||||
});
|
||||
|
||||
Ember.run.scheduleOnce('afterRender', this, this._triggerChange);
|
||||
|
|
|
@ -13,6 +13,7 @@ export default Ember.Component.extend({
|
|||
time: null,
|
||||
isCustom: Ember.computed.equal('selection', PICK_DATE_AND_TIME),
|
||||
isBasedOnLastPost: Ember.computed.equal('selection', SET_BASED_ON_LAST_POST),
|
||||
displayLabel: null,
|
||||
|
||||
init() {
|
||||
this._super();
|
||||
|
@ -64,6 +65,10 @@ export default Ember.Component.extend({
|
|||
}
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
this.set('displayLabel', I18n.t(this.get('label') || 'topic.topic_status_update.when'));
|
||||
},
|
||||
|
||||
@computed("statusType", "input", "isCustom", "date", "time", "willCloseImmediately", "categoryId")
|
||||
showTopicStatusInfo(statusType, input, isCustom, date, time, willCloseImmediately, categoryId) {
|
||||
if (!statusType || willCloseImmediately) return false;
|
||||
|
|
|
@ -25,5 +25,3 @@ registerUnbound('format-date', function(val, params) {
|
|||
return new Handlebars.SafeString(autoUpdatingRelativeAge(date, {format: format, title: title, leaveAgo: leaveAgo}));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="auto-update-input">
|
||||
<div class="control-group">
|
||||
<label>{{i18n "topic.topic_status_update.when"}}</label>
|
||||
<label>{{displayLabel}}</label>
|
||||
|
||||
{{auto-update-input-selector
|
||||
valueAttribute="id"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.suspend-user-modal {
|
||||
|
||||
.duration-controls {
|
||||
.until-controls {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class Admin::UsersController < Admin::AdminController
|
|||
|
||||
def suspend
|
||||
guardian.ensure_can_suspend!(@user)
|
||||
@user.suspended_till = params[:duration].to_i.days.from_now
|
||||
@user.suspended_till = params[:suspend_until]
|
||||
@user.suspended_at = DateTime.now
|
||||
|
||||
message = params[:message]
|
||||
|
|
|
@ -17,6 +17,7 @@ class AdminDetailedUserSerializer < AdminUserSerializer
|
|||
:can_be_deleted,
|
||||
:can_be_anonymized,
|
||||
:suspend_reason,
|
||||
:suspended_till,
|
||||
:primary_group_id,
|
||||
:badge_count,
|
||||
:warnings_received_count,
|
||||
|
|
|
@ -3264,7 +3264,6 @@ en:
|
|||
suspend_failed: "Something went wrong suspending this user {{error}}"
|
||||
unsuspend_failed: "Something went wrong unsuspending this user {{error}}"
|
||||
suspend_duration: "How long will the user be suspended for?"
|
||||
suspend_duration_units: "(days)"
|
||||
suspend_reason_label: "Why are you suspending? This text <b>will be visible to everyone</b> on this user's profile page, and will be shown to the user when they try to log in. Keep it short."
|
||||
suspend_reason_hidden_label: "Why are you suspending? This text will be shown to the user when they try to log in. Keep it short."
|
||||
suspend_reason: "Reason"
|
||||
|
@ -3272,6 +3271,7 @@ en:
|
|||
suspend_message: "Email Message"
|
||||
suspend_message_placeholder: "Optionally, provide more information about the suspension and it will be emailed to the user."
|
||||
suspended_by: "Suspended by"
|
||||
suspended_until: "(until %{until})"
|
||||
delete_all_posts: "Delete all posts"
|
||||
|
||||
# keys ending with _MF use message format, see https://meta.discourse.org/t/message-format-support-for-localization/7035 for details
|
||||
|
|
|
@ -128,7 +128,7 @@ describe Admin::UsersController do
|
|||
put(
|
||||
:suspend,
|
||||
user_id: user.id,
|
||||
duration: 10,
|
||||
suspend_until: 5.hours.from_now,
|
||||
reason: "because I said so",
|
||||
format: :json
|
||||
)
|
||||
|
@ -149,15 +149,14 @@ describe Admin::UsersController do
|
|||
:critical_user_email,
|
||||
has_entries(
|
||||
type: :account_suspended,
|
||||
user_id: user.id,
|
||||
message: "long reason"
|
||||
user_id: user.id
|
||||
)
|
||||
)
|
||||
|
||||
put(
|
||||
:suspend,
|
||||
user_id: user.id,
|
||||
duration: 10,
|
||||
suspend_until: 10.days.from_now,
|
||||
reason: "short reason",
|
||||
message: "long reason",
|
||||
format: :json
|
||||
|
@ -168,10 +167,12 @@ describe Admin::UsersController do
|
|||
expect(log).to be_present
|
||||
expect(log.details).to match(/short reason/)
|
||||
expect(log.details).to match(/long reason/)
|
||||
end
|
||||
|
||||
it "also revoke any api keys" do
|
||||
User.any_instance.expects(:revoke_api_key)
|
||||
put :suspend, params: { user_id: evil_trout.id }, format: :json
|
||||
expect(log.context).to match(/long reason/)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -201,10 +201,9 @@ describe Jobs::UserEmail do
|
|||
post,
|
||||
:user_mentioned,
|
||||
notification,
|
||||
notification.notification_type,
|
||||
notification.data_hash,
|
||||
nil,
|
||||
nil)
|
||||
notification_type: notification.notification_type,
|
||||
notification_data_hash: notification.data_hash
|
||||
)
|
||||
|
||||
expect(message).to eq nil
|
||||
expect(err.skipped_reason).to match(/notification.*already/)
|
||||
|
|
|
@ -43,12 +43,14 @@ QUnit.test("suspend, then unsuspend a user", assert => {
|
|||
|
||||
andThen(() => {
|
||||
assert.equal(find('.perform-suspend[disabled]').length, 1, 'disabled by default');
|
||||
find('.suspend-until .combobox').select2('val', 'tomorrow');
|
||||
find('.suspend-until .combobox').trigger('change', 'tomorrow');
|
||||
});
|
||||
fillIn('.suspend-duration', 12);
|
||||
|
||||
fillIn('.suspend-reason', "for breaking the rules");
|
||||
fillIn('.suspend-message', "this is an email reason why");
|
||||
andThen(() => {
|
||||
assert.equal(find('.perform-suspend[disabled]').length, 0);
|
||||
assert.equal(find('.perform-suspend[disabled]').length, 0, 'no longer disabled');
|
||||
});
|
||||
click('.perform-suspend');
|
||||
andThen(() => {
|
||||
|
|
Loading…
Reference in New Issue
Block a user