mirror of
https://github.com/discourse/discourse.git
synced 2025-03-06 03:09:43 +00:00
UX: separate custom from automatic groups in user admin
REFACTOR: some moar ES6 refactoring
This commit is contained in:
parent
56e01a766b
commit
9cbd0f8e78
@ -1,31 +1,36 @@
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'div',
|
||||
|
||||
didInsertElement: function(){
|
||||
_init: function(){
|
||||
this.$("input").select2({
|
||||
multiple: true,
|
||||
width: '100%',
|
||||
query: function(opts){
|
||||
opts.callback({
|
||||
results: this.get("available").map(this._format)
|
||||
});
|
||||
query: function(opts) {
|
||||
opts.callback({ results: this.get("available").map(this._format) });
|
||||
}.bind(this)
|
||||
}).on("change", function(evt) {
|
||||
if (evt.added){
|
||||
this.triggerAction({action: "groupAdded",
|
||||
actionContext: this.get("available"
|
||||
).findBy("id", evt.added.id)});
|
||||
this.triggerAction({
|
||||
action: "groupAdded",
|
||||
actionContext: this.get("available").findBy("id", evt.added.id)
|
||||
});
|
||||
} else if (evt.removed) {
|
||||
this.triggerAction({action:"groupRemoved",
|
||||
actionContext: this.get("selected"
|
||||
).findBy("id", evt.removed.id)});
|
||||
this.triggerAction({
|
||||
action:"groupRemoved",
|
||||
actionContext: evt.removed.id
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
this._refreshOnReset();
|
||||
},
|
||||
|
||||
_format: function(item){
|
||||
return {"text": item.name, "id": item.id, "locked": item.automatic};
|
||||
this._refreshOnReset();
|
||||
}.on("didInsertElement"),
|
||||
|
||||
_format(item) {
|
||||
return {
|
||||
"text": item.name,
|
||||
"id": item.id,
|
||||
"locked": item.automatic
|
||||
};
|
||||
},
|
||||
|
||||
_refreshOnReset: function() {
|
||||
|
@ -11,58 +11,61 @@ export default ObjectController.extend(CanCheckEmails, {
|
||||
|
||||
primaryGroupDirty: Discourse.computed.propertyNotEqual('originalPrimaryGroupId', 'primary_group_id'),
|
||||
|
||||
custom_groups: Ember.computed.filter("model.groups", function(g){
|
||||
return (!g.automatic && g.visible);
|
||||
}),
|
||||
automaticGroups: function() {
|
||||
return this.get("model.automaticGroups").map((g) => g.name).join(", ");
|
||||
}.property("model.automaticGroups"),
|
||||
|
||||
userFields: function() {
|
||||
var siteUserFields = this.site.get('user_fields'),
|
||||
userFields = this.get('user_fields');
|
||||
const siteUserFields = this.site.get('user_fields'),
|
||||
userFields = this.get('user_fields');
|
||||
|
||||
if (!Ember.isEmpty(siteUserFields)) {
|
||||
return siteUserFields.map(function(uf) {
|
||||
var value = userFields ? userFields[uf.get('id').toString()] : null;
|
||||
return {name: uf.get('name'), value: value};
|
||||
let value = userFields ? userFields[uf.get('id').toString()] : null;
|
||||
return { name: uf.get('name'), value: value };
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}.property('user_fields.@each'),
|
||||
|
||||
actions: {
|
||||
toggleTitleEdit: function() {
|
||||
toggleTitleEdit() {
|
||||
this.toggleProperty('editingTitle');
|
||||
},
|
||||
|
||||
saveTitle: function() {
|
||||
Discourse.ajax("/users/" + this.get('username').toLowerCase(), {
|
||||
saveTitle() {
|
||||
const self = this;
|
||||
|
||||
return Discourse.ajax("/users/" + this.get('username').toLowerCase(), {
|
||||
data: {title: this.get('title')},
|
||||
type: 'PUT'
|
||||
}).then(null, function(e){
|
||||
}).catch(function(e) {
|
||||
bootbox.alert(I18n.t("generic_error_with_reason", {error: "http: " + e.status + " - " + e.body}));
|
||||
}).finally(function() {
|
||||
self.send('toggleTitleEdit');
|
||||
});
|
||||
|
||||
this.send('toggleTitleEdit');
|
||||
},
|
||||
|
||||
generateApiKey: function() {
|
||||
generateApiKey() {
|
||||
this.get('model').generateApiKey();
|
||||
},
|
||||
|
||||
groupAdded: function(added){
|
||||
groupAdded(added) {
|
||||
this.get('model').groupAdded(added).catch(function() {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
});
|
||||
},
|
||||
|
||||
groupRemoved: function(removed){
|
||||
this.get('model').groupRemoved(removed).catch(function() {
|
||||
groupRemoved(groupId) {
|
||||
this.get('model').groupRemoved(groupId).catch(function() {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
});
|
||||
},
|
||||
|
||||
savePrimaryGroup: function() {
|
||||
var self = this;
|
||||
Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", {
|
||||
savePrimaryGroup() {
|
||||
const self = this;
|
||||
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", {
|
||||
type: 'PUT',
|
||||
data: {primary_group_id: this.get('primary_group_id')}
|
||||
}).then(function () {
|
||||
@ -72,33 +75,41 @@ export default ObjectController.extend(CanCheckEmails, {
|
||||
});
|
||||
},
|
||||
|
||||
resetPrimaryGroup: function() {
|
||||
resetPrimaryGroup() {
|
||||
this.set('primary_group_id', this.get('originalPrimaryGroupId'));
|
||||
},
|
||||
|
||||
regenerateApiKey: function() {
|
||||
var self = this;
|
||||
bootbox.confirm(I18n.t("admin.api.confirm_regen"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
||||
if (result) {
|
||||
self.get('model').generateApiKey();
|
||||
regenerateApiKey() {
|
||||
const self = this;
|
||||
|
||||
bootbox.confirm(
|
||||
I18n.t("admin.api.confirm_regen"),
|
||||
I18n.t("no_value"),
|
||||
I18n.t("yes_value"),
|
||||
function(result) {
|
||||
if (result) { self.get('model').generateApiKey(); }
|
||||
}
|
||||
});
|
||||
);
|
||||
},
|
||||
|
||||
revokeApiKey: function() {
|
||||
var self = this;
|
||||
bootbox.confirm(I18n.t("admin.api.confirm_revoke"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
||||
if (result) {
|
||||
self.get('model').revokeApiKey();
|
||||
revokeApiKey() {
|
||||
const self = this;
|
||||
|
||||
bootbox.confirm(
|
||||
I18n.t("admin.api.confirm_revoke"),
|
||||
I18n.t("no_value"),
|
||||
I18n.t("yes_value"),
|
||||
function(result) {
|
||||
if (result) { self.get('model').revokeApiKey(); }
|
||||
}
|
||||
});
|
||||
);
|
||||
},
|
||||
|
||||
anonymize: function() {
|
||||
anonymize() {
|
||||
this.get('model').anonymize();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
this.get('model').destroy();
|
||||
}
|
||||
}
|
||||
|
@ -1,58 +1,36 @@
|
||||
/**
|
||||
Our data model for dealing with users from the admin section.
|
||||
const AdminUser = Discourse.User.extend({
|
||||
|
||||
@class AdminUser
|
||||
@extends Discourse.Model
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminUser = Discourse.User.extend({
|
||||
customGroups: Em.computed.filter("groups", (g) => !g.automatic && g.visible && Discourse.Group.create(g)),
|
||||
automaticGroups: Em.computed.filter("groups", (g) => g.automatic && Discourse.Group.create(g)),
|
||||
|
||||
/**
|
||||
Generates an API key for the user. Will regenerate if they already have one.
|
||||
|
||||
@method generateApiKey
|
||||
@returns {Promise} a promise that resolves to the newly generated API key
|
||||
**/
|
||||
generateApiKey: function() {
|
||||
var self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/generate_api_key", {type: 'POST'}).then(function (result) {
|
||||
var apiKey = Discourse.ApiKey.create(result.api_key);
|
||||
generateApiKey() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/generate_api_key", {
|
||||
type: 'POST'
|
||||
}).then(function (result) {
|
||||
const apiKey = Discourse.ApiKey.create(result.api_key);
|
||||
self.set('api_key', apiKey);
|
||||
return apiKey;
|
||||
});
|
||||
},
|
||||
|
||||
groupAdded: function(added){
|
||||
var self = this;
|
||||
groupAdded(added) {
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/groups", {
|
||||
type: 'POST',
|
||||
data: {group_id: added.id}
|
||||
}).then(function () {
|
||||
self.get('groups').pushObject(added);
|
||||
});
|
||||
data: { group_id: added.id }
|
||||
}).then(() => this.get('groups').pushObject(added));
|
||||
},
|
||||
|
||||
groupRemoved: function(removed){
|
||||
var self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/groups/" + removed.id, {
|
||||
groupRemoved(groupId) {
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/groups/" + groupId, {
|
||||
type: 'DELETE'
|
||||
}).then(function () {
|
||||
self.set('groups.[]', self.get('groups').rejectBy("id", removed.id));
|
||||
});
|
||||
}).then(() => this.set('groups.[]', this.get('groups').rejectBy("id", groupId)));
|
||||
},
|
||||
|
||||
/**
|
||||
Revokes a user's current API key
|
||||
|
||||
@method revokeApiKey
|
||||
@returns {Promise} a promise that resolves when the API key has been deleted
|
||||
**/
|
||||
revokeApiKey: function() {
|
||||
var self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_api_key", {type: 'DELETE'}).then(function () {
|
||||
self.set('api_key', null);
|
||||
});
|
||||
revokeApiKey() {
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_api_key", {
|
||||
type: 'DELETE'
|
||||
}).then(() => this.set('api_key', null));
|
||||
},
|
||||
|
||||
deleteAllPostsExplanation: function() {
|
||||
@ -70,99 +48,111 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
}
|
||||
}.property('can_delete_all_posts', 'deleteForbidden'),
|
||||
|
||||
deleteAllPosts: function() {
|
||||
var user = this;
|
||||
var message = I18n.t('admin.user.delete_all_posts_confirm', {posts: user.get('post_count'), topics: user.get('topic_count')});
|
||||
var buttons = [{
|
||||
"label": I18n.t("composer.cancel"),
|
||||
"class": "cancel-inline",
|
||||
"link": true
|
||||
}, {
|
||||
"label": '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("admin.user.delete_all_posts"),
|
||||
"class": "btn btn-danger",
|
||||
"callback": function() {
|
||||
Discourse.ajax("/admin/users/" + (user.get('id')) + "/delete_all_posts", {type: 'PUT'}).then(function(){
|
||||
user.set('post_count', 0);
|
||||
});
|
||||
}
|
||||
}];
|
||||
bootbox.dialog(message, buttons, {"classes": "delete-all-posts"});
|
||||
deleteAllPosts() {
|
||||
const user = this,
|
||||
message = I18n.t('admin.user.delete_all_posts_confirm', { posts: user.get('post_count'), topics: user.get('topic_count') }),
|
||||
buttons = [{
|
||||
"label": I18n.t("composer.cancel"),
|
||||
"class": "cancel-inline",
|
||||
"link": true
|
||||
}, {
|
||||
"label": '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("admin.user.delete_all_posts"),
|
||||
"class": "btn btn-danger",
|
||||
"callback": function() {
|
||||
Discourse.ajax("/admin/users/" + user.get('id') + "/delete_all_posts", {
|
||||
type: 'PUT'
|
||||
}).then(() => user.set('post_count', 0));
|
||||
}
|
||||
}];
|
||||
bootbox.dialog(message, buttons, { "classes": "delete-all-posts" });
|
||||
},
|
||||
|
||||
// Revoke the user's admin access
|
||||
revokeAdmin: function() {
|
||||
this.set('admin', false);
|
||||
this.set('can_grant_admin', true);
|
||||
this.set('can_revoke_admin', false);
|
||||
return Discourse.ajax("/admin/users/" + (this.get('id')) + "/revoke_admin", {type: 'PUT'});
|
||||
},
|
||||
|
||||
grantAdmin: function() {
|
||||
this.set('admin', true);
|
||||
this.set('can_grant_admin', false);
|
||||
this.set('can_revoke_admin', true);
|
||||
var self = this;
|
||||
|
||||
Discourse.ajax("/admin/users/" + (this.get('id')) + "/grant_admin", {type: 'PUT'})
|
||||
.then(null, function(e) {
|
||||
self.set('admin', false);
|
||||
self.set('can_grant_admin', true);
|
||||
self.set('can_revoke_admin', false);
|
||||
|
||||
var error;
|
||||
if (e.responseJSON && e.responseJSON.error) {
|
||||
error = e.responseJSON.error;
|
||||
}
|
||||
error = error || I18n.t('admin.user.grant_admin_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
revokeAdmin() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_admin", {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
self.setProperties({
|
||||
admin: false,
|
||||
can_grant_admin: true,
|
||||
can_revoke_admin: false
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Revoke the user's moderation access
|
||||
revokeModeration: function() {
|
||||
this.set('moderator', false);
|
||||
this.set('can_grant_moderation', true);
|
||||
this.set('can_revoke_moderation', false);
|
||||
return Discourse.ajax("/admin/users/" + (this.get('id')) + "/revoke_moderation", {type: 'PUT'});
|
||||
grantAdmin() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/grant_admin", {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
self.setProperties({
|
||||
admin: true,
|
||||
can_grant_admin: false,
|
||||
can_revoke_admin: true
|
||||
});
|
||||
}).catch(function(e) {
|
||||
let error;
|
||||
if (e.responseJSON && e.responseJSON.error) {
|
||||
error = e.responseJSON.error;
|
||||
}
|
||||
error = error || I18n.t('admin.user.grant_admin_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
grantModeration: function() {
|
||||
this.set('moderator', true);
|
||||
this.set('can_grant_moderation', false);
|
||||
this.set('can_revoke_moderation', true);
|
||||
var self = this;
|
||||
Discourse.ajax("/admin/users/" + (this.get('id')) + "/grant_moderation", {type: 'PUT'})
|
||||
.then(null, function(e) {
|
||||
self.set('moderator', false);
|
||||
self.set('can_grant_moderation', true);
|
||||
self.set('can_revoke_moderation', false);
|
||||
|
||||
var error;
|
||||
if (e.responseJSON && e.responseJSON.error) {
|
||||
error = e.responseJSON.error;
|
||||
}
|
||||
error = error || I18n.t('admin.user.grant_moderation_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
revokeModeration() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/revoke_moderation", {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
self.setProperties({
|
||||
moderator: false,
|
||||
can_grant_moderation: true,
|
||||
can_revoke_moderation: false
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
refreshBrowsers: function() {
|
||||
Discourse.ajax("/admin/users/" + (this.get('id')) + "/refresh_browsers", {type: 'POST'});
|
||||
bootbox.alert(I18n.t("admin.user.refresh_browsers_message"));
|
||||
grantModeration() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/grant_moderation", {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
self.setProperties({
|
||||
moderator: true,
|
||||
can_grant_moderation: false,
|
||||
can_revoke_moderation: true
|
||||
});
|
||||
}).catch(function(e) {
|
||||
let error;
|
||||
if (e.responseJSON && e.responseJSON.error) {
|
||||
error = e.responseJSON.error;
|
||||
}
|
||||
error = error || I18n.t('admin.user.grant_moderation_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
approve: function() {
|
||||
this.set('can_approve', false);
|
||||
this.set('approved', true);
|
||||
this.set('approved_by', Discourse.User.current());
|
||||
Discourse.ajax("/admin/users/" + (this.get('id')) + "/approve", {type: 'PUT'});
|
||||
refreshBrowsers() {
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/refresh_browsers", {
|
||||
type: 'POST'
|
||||
}).finally(() => bootbox.alert(I18n.t("admin.user.refresh_browsers_message")));
|
||||
},
|
||||
|
||||
username_lower: (function() {
|
||||
return this.get('username').toLowerCase();
|
||||
}).property('username'),
|
||||
approve() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/admin/users/" + this.get('id') + "/approve", {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
self.setProperties({
|
||||
can_approve: false,
|
||||
approved: true,
|
||||
approved_by: Discourse.User.current()
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setOriginalTrustLevel: function() {
|
||||
setOriginalTrustLevel() {
|
||||
this.set('originalTrustLevel', this.get('trust_level'));
|
||||
},
|
||||
|
||||
@ -172,16 +162,14 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
|
||||
dirty: Discourse.computed.propertyNotEqual('originalTrustLevel', 'trustLevel.id'),
|
||||
|
||||
saveTrustLevel: function() {
|
||||
Discourse.ajax("/admin/users/" + this.id + "/trust_level", {
|
||||
saveTrustLevel() {
|
||||
return Discourse.ajax("/admin/users/" + this.id + "/trust_level", {
|
||||
type: 'PUT',
|
||||
data: {level: this.get('trustLevel.id')}
|
||||
}).then(function () {
|
||||
// succeeded
|
||||
data: { level: this.get('trustLevel.id') }
|
||||
}).then(function() {
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failure
|
||||
var error;
|
||||
}).catch(function(e) {
|
||||
let error;
|
||||
if (e.responseJSON && e.responseJSON.errors) {
|
||||
error = e.responseJSON.errors[0];
|
||||
}
|
||||
@ -190,20 +178,18 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
});
|
||||
},
|
||||
|
||||
restoreTrustLevel: function() {
|
||||
restoreTrustLevel() {
|
||||
this.set('trustLevel.id', this.get('originalTrustLevel'));
|
||||
},
|
||||
|
||||
lockTrustLevel: function(locked) {
|
||||
Discourse.ajax("/admin/users/" + this.id + "/trust_level_lock", {
|
||||
lockTrustLevel(locked) {
|
||||
return Discourse.ajax("/admin/users/" + this.id + "/trust_level_lock", {
|
||||
type: 'PUT',
|
||||
data: { locked: !!locked }
|
||||
}).then(function() {
|
||||
// succeeded
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failure
|
||||
var error;
|
||||
}).catch(function(e) {
|
||||
let error;
|
||||
if (e.responseJSON && e.responseJSON.errors) {
|
||||
error = e.responseJSON.errors[0];
|
||||
}
|
||||
@ -212,7 +198,7 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
});
|
||||
},
|
||||
|
||||
canLockTrustLevel: function(){
|
||||
canLockTrustLevel: function() {
|
||||
return this.get('trust_level') < 4;
|
||||
}.property('trust_level'),
|
||||
|
||||
@ -220,51 +206,45 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
canSuspend: Em.computed.not('staff'),
|
||||
|
||||
suspendDuration: function() {
|
||||
var suspended_at = moment(this.suspended_at);
|
||||
var suspended_till = moment(this.suspended_till);
|
||||
const suspended_at = moment(this.suspended_at),
|
||||
suspended_till = moment(this.suspended_till);
|
||||
return suspended_at.format('L') + " - " + suspended_till.format('L');
|
||||
}.property('suspended_till', 'suspended_at'),
|
||||
|
||||
suspend: function(duration, reason) {
|
||||
suspend(duration, reason) {
|
||||
return Discourse.ajax("/admin/users/" + this.id + "/suspend", {
|
||||
type: 'PUT',
|
||||
data: {duration: duration, reason: reason}
|
||||
data: { duration: duration, reason: reason }
|
||||
});
|
||||
},
|
||||
|
||||
unsuspend: function() {
|
||||
Discourse.ajax("/admin/users/" + this.id + "/unsuspend", {
|
||||
unsuspend() {
|
||||
return Discourse.ajax("/admin/users/" + this.id + "/unsuspend", {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
// succeeded
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
var error = I18n.t('admin.user.unsuspend_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
log_out: function(){
|
||||
Discourse.ajax("/admin/users/" + this.id + "/log_out", {
|
||||
type: 'POST',
|
||||
data: { username_or_email: this.get('username') }
|
||||
}).then(
|
||||
function(){
|
||||
bootbox.alert(I18n.t("admin.user.logged_out"));
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
impersonate: function() {
|
||||
Discourse.ajax("/admin/impersonate", {
|
||||
log_out() {
|
||||
return Discourse.ajax("/admin/users/" + this.id + "/log_out", {
|
||||
type: 'POST',
|
||||
data: { username_or_email: this.get('username') }
|
||||
}).then(function() {
|
||||
bootbox.alert(I18n.t("admin.user.logged_out"));
|
||||
});
|
||||
},
|
||||
|
||||
impersonate() {
|
||||
return Discourse.ajax("/admin/impersonate", {
|
||||
type: 'POST',
|
||||
data: { username_or_email: this.get('username') }
|
||||
}).then(function() {
|
||||
// succeeded
|
||||
document.location = "/";
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
if (e.status === 404) {
|
||||
bootbox.alert(I18n.t('admin.impersonate.not_found'));
|
||||
} else {
|
||||
@ -273,56 +253,57 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
});
|
||||
},
|
||||
|
||||
activate: function() {
|
||||
Discourse.ajax('/admin/users/' + this.id + '/activate', {type: 'PUT'}).then(function() {
|
||||
// succeeded
|
||||
activate() {
|
||||
return Discourse.ajax('/admin/users/' + this.id + '/activate', {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
var error = I18n.t('admin.user.activate_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
deactivate: function() {
|
||||
Discourse.ajax('/admin/users/' + this.id + '/deactivate', {type: 'PUT'}).then(function() {
|
||||
// succeeded
|
||||
deactivate() {
|
||||
return Discourse.ajax('/admin/users/' + this.id + '/deactivate', {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
var error = I18n.t('admin.user.deactivate_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
unblock: function() {
|
||||
Discourse.ajax('/admin/users/' + this.id + '/unblock', {type: 'PUT'}).then(function() {
|
||||
// succeeded
|
||||
unblock() {
|
||||
return Discourse.ajax('/admin/users/' + this.id + '/unblock', {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
var error = I18n.t('admin.user.unblock_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
block: function() {
|
||||
Discourse.ajax('/admin/users/' + this.id + '/block', {type: 'PUT'}).then(function() {
|
||||
// succeeded
|
||||
block() {
|
||||
return Discourse.ajax('/admin/users/' + this.id + '/block', {
|
||||
type: 'PUT'
|
||||
}).then(function() {
|
||||
window.location.reload();
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
var error = I18n.t('admin.user.block_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
},
|
||||
|
||||
sendActivationEmail: function() {
|
||||
Discourse.ajax('/users/action/send_activation_email', {data: {username: this.get('username')}, type: 'POST'}).then(function() {
|
||||
// succeeded
|
||||
sendActivationEmail() {
|
||||
return Discourse.ajax('/users/action/send_activation_email', {
|
||||
type: 'POST',
|
||||
data: { username: this.get('username') }
|
||||
}).then(function() {
|
||||
bootbox.alert( I18n.t('admin.user.activation_email_sent') );
|
||||
}, function(e) {
|
||||
// failed
|
||||
}).catch(function(e) {
|
||||
var error = I18n.t('admin.user.send_activation_email_failed', { error: "http: " + e.status + " - " + e.body });
|
||||
bootbox.alert(error);
|
||||
});
|
||||
@ -330,11 +311,14 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
|
||||
anonymizeForbidden: Em.computed.not("can_be_anonymized"),
|
||||
|
||||
anonymize: function() {
|
||||
var user = this;
|
||||
anonymize() {
|
||||
const user = this,
|
||||
message = I18n.t("admin.user.anonymize_confirm");
|
||||
|
||||
var performAnonymize = function() {
|
||||
Discourse.ajax("/admin/users/" + user.get('id') + '/anonymize.json', {type: 'PUT'}).then(function(data) {
|
||||
const performAnonymize = function() {
|
||||
return Discourse.ajax("/admin/users/" + user.get('id') + '/anonymize.json', {
|
||||
type: 'PUT'
|
||||
}).then(function(data) {
|
||||
if (data.success) {
|
||||
if (data.username) {
|
||||
document.location = "/admin/users/" + data.username;
|
||||
@ -347,26 +331,22 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
user.setProperties(data.user);
|
||||
}
|
||||
}
|
||||
}, function() {
|
||||
}).catch(function() {
|
||||
bootbox.alert(I18n.t("admin.user.anonymize_failed"));
|
||||
});
|
||||
};
|
||||
|
||||
var message = I18n.t("admin.user.anonymize_confirm");
|
||||
|
||||
var buttons = [{
|
||||
const buttons = [{
|
||||
"label": I18n.t("composer.cancel"),
|
||||
"class": "cancel",
|
||||
"link": true
|
||||
}, {
|
||||
"label": '<i class="fa fa-exclamation-triangle"></i>' + I18n.t('admin.user.anonymize_yes'),
|
||||
"class": "btn btn-danger",
|
||||
"callback": function(){
|
||||
performAnonymize();
|
||||
}
|
||||
"callback": function() { performAnonymize(); }
|
||||
}];
|
||||
|
||||
bootbox.dialog(message, buttons, {"classes": "delete-user-modal"});
|
||||
bootbox.dialog(message, buttons, { "classes": "delete-user-modal" });
|
||||
},
|
||||
|
||||
deleteForbidden: Em.computed.not("canBeDeleted"),
|
||||
@ -383,12 +363,13 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
}
|
||||
}.property('deleteForbidden'),
|
||||
|
||||
destroy: function(opts) {
|
||||
var user = this;
|
||||
var location = document.location.pathname;
|
||||
destroy(opts) {
|
||||
const user = this,
|
||||
message = I18n.t("admin.user.delete_confirm"),
|
||||
location = document.location.pathname;
|
||||
|
||||
var performDestroy = function(block) {
|
||||
var formData = { context: location };
|
||||
const performDestroy = function(block) {
|
||||
let formData = { context: location };
|
||||
if (block) {
|
||||
formData["block_email"] = true;
|
||||
formData["block_urls"] = true;
|
||||
@ -397,7 +378,7 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
if (opts && opts.deletePosts) {
|
||||
formData["delete_posts"] = true;
|
||||
}
|
||||
Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
|
||||
return Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
|
||||
type: 'DELETE',
|
||||
data: formData
|
||||
}).then(function(data) {
|
||||
@ -413,47 +394,42 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
user.setProperties(data.user);
|
||||
}
|
||||
}
|
||||
}, function() {
|
||||
}).catch(function() {
|
||||
Discourse.AdminUser.find( user.get('username') ).then(function(u){ user.setProperties(u); });
|
||||
bootbox.alert(I18n.t("admin.user.delete_failed"));
|
||||
});
|
||||
};
|
||||
|
||||
var message = I18n.t("admin.user.delete_confirm");
|
||||
|
||||
var buttons = [{
|
||||
const buttons = [{
|
||||
"label": I18n.t("composer.cancel"),
|
||||
"class": "cancel",
|
||||
"link": true
|
||||
}, {
|
||||
"label": I18n.t('admin.user.delete_dont_block'),
|
||||
"class": "btn",
|
||||
"callback": function(){
|
||||
performDestroy(false);
|
||||
}
|
||||
"callback": function(){ performDestroy(false); }
|
||||
}, {
|
||||
"label": '<i class="fa fa-exclamation-triangle"></i>' + I18n.t('admin.user.delete_and_block'),
|
||||
"class": "btn btn-danger",
|
||||
"callback": function(){
|
||||
performDestroy(true);
|
||||
}
|
||||
"callback": function(){ performDestroy(true); }
|
||||
}];
|
||||
|
||||
bootbox.dialog(message, buttons, {"classes": "delete-user-modal"});
|
||||
bootbox.dialog(message, buttons, { "classes": "delete-user-modal" });
|
||||
},
|
||||
|
||||
deleteAsSpammer: function(successCallback) {
|
||||
var user = this;
|
||||
deleteAsSpammer(successCallback) {
|
||||
const user = this;
|
||||
|
||||
user.checkEmail().then(function() {
|
||||
var data = {
|
||||
const data = {
|
||||
posts: user.get('post_count'),
|
||||
topics: user.get('topic_count'),
|
||||
email: user.get('email') || I18n.t("flagging.hidden_email_address"),
|
||||
ip_address: user.get('ip_address') || I18n.t("flagging.ip_address_missing")
|
||||
};
|
||||
var message = I18n.t('flagging.delete_confirm', data);
|
||||
var buttons = [{
|
||||
};
|
||||
|
||||
const message = I18n.t('flagging.delete_confirm', data),
|
||||
buttons = [{
|
||||
"label": I18n.t("composer.cancel"),
|
||||
"class": "cancel-inline",
|
||||
"link": true
|
||||
@ -461,7 +437,7 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
"label": '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("flagging.yes_delete_spammer"),
|
||||
"class": "btn btn-danger",
|
||||
"callback": function() {
|
||||
Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
|
||||
return Discourse.ajax("/admin/users/" + user.get('id') + '.json', {
|
||||
type: 'DELETE',
|
||||
data: {
|
||||
delete_posts: true,
|
||||
@ -477,23 +453,24 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
} else {
|
||||
bootbox.alert(I18n.t("admin.user.delete_failed"));
|
||||
}
|
||||
}, function() {
|
||||
}).catch(function() {
|
||||
bootbox.alert(I18n.t("admin.user.delete_failed"));
|
||||
});
|
||||
}
|
||||
}];
|
||||
|
||||
bootbox.dialog(message, buttons, {"classes": "flagging-delete-spammer"});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
loadDetails: function() {
|
||||
var model = this;
|
||||
if (model.get('loadedDetails')) { return Ember.RSVP.resolve(model); }
|
||||
loadDetails() {
|
||||
const user = this;
|
||||
|
||||
return Discourse.AdminUser.find(model.get('username_lower')).then(function (result) {
|
||||
model.setProperties(result);
|
||||
model.set('loadedDetails', true);
|
||||
if (user.get('loadedDetails')) { return Ember.RSVP.resolve(user); }
|
||||
|
||||
return Discourse.AdminUser.find(user.get('username_lower')).then(function (result) {
|
||||
user.setProperties(result);
|
||||
user.set('loadedDetails', true);
|
||||
});
|
||||
},
|
||||
|
||||
@ -517,29 +494,25 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||
|
||||
});
|
||||
|
||||
Discourse.AdminUser.reopenClass({
|
||||
AdminUser.reopenClass({
|
||||
|
||||
bulkApprove: function(users) {
|
||||
bulkApprove(users) {
|
||||
_.each(users, function(user) {
|
||||
user.set('approved', true);
|
||||
user.set('can_approve', false);
|
||||
return user.set('selected', false);
|
||||
user.setProperties({
|
||||
approved: true,
|
||||
can_approve: false,
|
||||
selected: false
|
||||
});
|
||||
});
|
||||
|
||||
bootbox.alert(I18n.t("admin.user.approve_bulk_success"));
|
||||
|
||||
return Discourse.ajax("/admin/users/approve-bulk", {
|
||||
type: 'PUT',
|
||||
data: {
|
||||
users: users.map(function(u) {
|
||||
return u.id;
|
||||
})
|
||||
}
|
||||
});
|
||||
data: { users: users.map((u) => u.id) }
|
||||
}).finally(() => bootbox.alert(I18n.t("admin.user.approve_bulk_success")));
|
||||
},
|
||||
|
||||
bulkReject: function(users) {
|
||||
_.each(users, function(user){
|
||||
bulkReject(users) {
|
||||
_.each(users, function(user) {
|
||||
user.set('can_approve', false);
|
||||
user.set('selected', false);
|
||||
});
|
||||
@ -547,26 +520,26 @@ Discourse.AdminUser.reopenClass({
|
||||
return Discourse.ajax("/admin/users/reject-bulk", {
|
||||
type: 'DELETE',
|
||||
data: {
|
||||
users: users.map(function(u) { return u.id; }),
|
||||
users: users.map((u) => u.id),
|
||||
context: window.location.pathname
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
find: function(username) {
|
||||
find(username) {
|
||||
return Discourse.ajax("/admin/users/" + username + ".json").then(function (result) {
|
||||
result.loadedDetails = true;
|
||||
return Discourse.AdminUser.create(result);
|
||||
});
|
||||
},
|
||||
|
||||
findAll: function(query, filter) {
|
||||
findAll(query, filter) {
|
||||
return Discourse.ajax("/admin/users/list/" + query + ".json", {
|
||||
data: filter
|
||||
}).then(function(users) {
|
||||
return users.map(function(u) {
|
||||
return Discourse.AdminUser.create(u);
|
||||
});
|
||||
return users.map((u) => Discourse.AdminUser.create(u));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export default AdminUser;
|
@ -3,20 +3,20 @@
|
||||
<div class='user-controls'>
|
||||
{{#if active}}
|
||||
{{#link-to 'user' model class="btn"}}
|
||||
<i class='fa fa-user'></i>
|
||||
{{fa-icon "user"}}
|
||||
{{i18n 'admin.user.show_public_profile'}}
|
||||
{{/link-to}}
|
||||
{{#if can_impersonate}}
|
||||
<button class='btn btn-danger' {{action "impersonate" target="content"}} title="{{i18n 'admin.impersonate.help'}}">
|
||||
<i class='fa fa-crosshairs'></i>
|
||||
{{i18n 'admin.impersonate.title'}}
|
||||
</button>
|
||||
<button class='btn btn-danger' {{action "impersonate" target="content"}} title="{{i18n 'admin.impersonate.help'}}">
|
||||
{{fa-icon "crosshairs"}}
|
||||
{{i18n 'admin.impersonate.title'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if currentUser.admin}}
|
||||
<button class='btn' {{action "log_out" target="content"}}>
|
||||
<i class='fa fa-power-off'></i>
|
||||
{{i18n 'admin.user.log_out'}}
|
||||
</button>
|
||||
<button class='btn' {{action "log_out" target="content"}}>
|
||||
{{fa-icon "power-off"}}
|
||||
{{i18n 'admin.user.log_out'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
@ -26,7 +26,7 @@
|
||||
<div class='value'>{{username}}</div>
|
||||
<div class='controls'>
|
||||
{{#link-to 'preferences.username' model class="btn"}}
|
||||
<i class='fa fa-pencil'></i>
|
||||
{{fa-icon "pencil"}}
|
||||
{{i18n 'user.change_username.title'}}
|
||||
{{/link-to}}
|
||||
</div>
|
||||
@ -75,28 +75,32 @@
|
||||
</div>
|
||||
<div class='controls'>
|
||||
{{#if editingTitle}}
|
||||
<button class='btn' {{action "saveTitle"}}>{{i18n 'admin.user.save_title'}}</button>
|
||||
<a href="#" {{action "toggleTitleEdit"}}>{{i18n 'cancel'}}</a>
|
||||
{{d-button action="saveTitle" label="admin.user.save_title"}}
|
||||
<a href {{action "toggleTitleEdit"}}>{{i18n 'cancel'}}</a>
|
||||
{{else}}
|
||||
<button class='btn' {{action "toggleTitleEdit"}}><i class="fa fa-pencil"></i>{{i18n 'admin.user.edit_title'}}</button>
|
||||
{{d-button action="toggleTitleEdit" icon="pencil" label="admin.user.edit_title"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if currentUser.admin}}
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n 'admin.groups.title'}}</div>
|
||||
<div class='field'>{{i18n 'admin.groups.automatic.title'}}</div>
|
||||
<div class='value'>{{automaticGroups}}</div>
|
||||
</div>
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n 'admin.groups.custom.title'}}</div>
|
||||
<div class='value'>
|
||||
{{admin-group-selector selected=model.groups available=availableGroups}}
|
||||
{{admin-group-selector selected=customGroups available=availableGroups}}
|
||||
</div>
|
||||
<div class='controls'>
|
||||
{{#if custom_groups}}
|
||||
{{#if customGroups}}
|
||||
{{i18n 'admin.groups.primary'}}
|
||||
{{combo-box content=custom_groups value=primary_group_id nameProperty="name" none="admin.groups.no_primary"}}
|
||||
{{combo-box content=customGroups value=primary_group_id nameProperty="name" none="admin.groups.no_primary"}}
|
||||
{{/if}}
|
||||
{{#if primaryGroupDirty}}
|
||||
<button class='btn ok no-text' {{action "savePrimaryGroup"}}><i class='fa fa-check'></i></button>
|
||||
<button class='btn cancel no-text' {{action "resetPrimaryGroup"}}><i class='fa fa-times'></i></button>
|
||||
{{d-button icon="check" class="ok no-text" action="savePrimaryGroup"}}
|
||||
{{d-button icon="times" class="cancel no-text" action="resetPrimaryGroup"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
@ -132,7 +136,7 @@
|
||||
{{i18n 'badges.badge_count' count=badge_count}}
|
||||
</div>
|
||||
<div class='controls'>
|
||||
{{#link-to 'adminUser.badges' this class="btn"}}<i class="fa fa-certificate"></i>{{i18n 'admin.badges.edit_badges'}}{{/link-to}}
|
||||
{{#link-to 'adminUser.badges' this class="btn"}}{{fa-icon "certificate"}}{{i18n 'admin.badges.edit_badges'}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
@ -165,13 +169,11 @@
|
||||
<div class='value'>
|
||||
{{#if approved}}
|
||||
{{i18n 'admin.user.approved_by'}}
|
||||
|
||||
{{#link-to 'adminUser' approvedBy}}{{avatar approvedBy imageSize="small"}}{{/link-to}}
|
||||
{{#link-to 'adminUser' approvedBy}}{{approvedBy.username}}{{/link-to}}
|
||||
{{else}}
|
||||
{{i18n 'no_value'}}
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
<div class='controls'>
|
||||
{{#if approved}}
|
||||
@ -179,7 +181,7 @@
|
||||
{{else}}
|
||||
{{#if can_approve}}
|
||||
<button class='btn' {{action "approve" target="content"}}>
|
||||
<i class='fa fa-check'></i>
|
||||
{{fa-icon "check"}}
|
||||
{{i18n 'admin.user.approve'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
@ -206,13 +208,13 @@
|
||||
{{else}}
|
||||
{{#if can_send_activation_email}}
|
||||
<button class='btn' {{action "sendActivationEmail" target="content"}}>
|
||||
<i class='fa fa-envelope'></i>
|
||||
{{fa-icon "envelope"}}
|
||||
{{i18n 'admin.user.send_activation_email'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if can_activate}}
|
||||
<button class='btn' {{action "activate" target="content"}}>
|
||||
<i class='fa fa-check'></i>
|
||||
{{fa-icon "check"}}
|
||||
{{i18n 'admin.user.activate'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
@ -222,19 +224,18 @@
|
||||
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n 'admin.api.key'}}</div>
|
||||
|
||||
{{#if api_key}}
|
||||
<div class='long-value'>
|
||||
{{api_key.key}}
|
||||
<button class='btn' {{action "regenerateApiKey"}}><i class="fa fa-undo"></i>{{i18n 'admin.api.regenerate'}}</button>
|
||||
<button {{action "revokeApiKey"}} class="btn"><i class="fa fa-times"></i>{{i18n 'admin.api.revoke'}}</button>
|
||||
{{d-button action="regenerateApiKey" icon="undo" label="admin.api.regenerate"}}
|
||||
{{d-button action="revokeApiKey" icon="times" label="admin.api.revoke"}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class='value'>
|
||||
—
|
||||
—
|
||||
</div>
|
||||
<div class='controls'>
|
||||
<button {{action "generateApiKey"}} class="btn"><i class="fa fa-key"></i>{{i18n 'admin.api.generate'}}</button>
|
||||
{{d-button action="generateApiKey" icon="key" label="admin.api.generate"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
@ -245,37 +246,36 @@
|
||||
<div class='controls'>
|
||||
{{#if can_revoke_admin}}
|
||||
<button class='btn' {{action "revokeAdmin" target="content"}}>
|
||||
<i class='fa fa-shield'></i>
|
||||
{{fa-icon "shield"}}
|
||||
{{i18n 'admin.user.revoke_admin'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if can_grant_admin}}
|
||||
<button class='btn' {{action "grantAdmin" target="content"}}>
|
||||
<i class='fa fa-shield'></i>
|
||||
{{fa-icon "shield"}}
|
||||
{{i18n 'admin.user.grant_admin'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n 'admin.user.moderator'}}</div>
|
||||
<div class='value'>{{moderator}}</div>
|
||||
<div class='controls'>
|
||||
{{#if can_revoke_moderation}}
|
||||
<button class='btn' {{action "revokeModeration" target="content"}}>
|
||||
<i class='fa fa-shield'></i>
|
||||
{{fa-icon "shield"}}
|
||||
{{i18n 'admin.user.revoke_moderation'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
{{#if can_grant_moderation}}
|
||||
<button class='btn' {{action "grantModeration" target="content"}}>
|
||||
<i class='fa fa-shield'></i>
|
||||
{{fa-icon "shield"}}
|
||||
{{i18n 'admin.user.grant_moderation'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class='display-row'>
|
||||
@ -284,8 +284,8 @@
|
||||
{{combo-box content=trustLevels value=trust_level nameProperty="detailedName"}}
|
||||
{{#if dirty}}
|
||||
<div>
|
||||
<button class='btn ok no-text' {{action "saveTrustLevel" target="content"}}><i class='fa fa-check'></i></button>
|
||||
<button class='btn cancel no-text' {{action "restoreTrustLevel" target="content"}}><i class='fa fa-times'></i></button>
|
||||
<button class='btn ok no-text' {{action "saveTrustLevel" target="content"}}>{{fa-icon "check"}}</button>
|
||||
<button class='btn cancel no-text' {{action "restoreTrustLevel" target="content"}}>{{fa-icon "times"}}</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
@ -300,7 +300,6 @@
|
||||
{{#if tl3Requirements}}
|
||||
{{#link-to 'adminUser.tl3Requirements' this class="btn"}}{{i18n 'admin.user.trust_level_3_requirements'}}{{/link-to}}
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -310,7 +309,7 @@
|
||||
<div class='controls'>
|
||||
{{#if isSuspended}}
|
||||
<button class='btn btn-danger' {{action "unsuspend" target="content"}}>
|
||||
<i class='fa fa-ban'></i>
|
||||
{{fa-icon "ban"}}
|
||||
{{i18n 'admin.user.unsuspend'}}
|
||||
</button>
|
||||
{{suspendDuration}}
|
||||
@ -318,7 +317,7 @@
|
||||
{{else}}
|
||||
{{#if canSuspend}}
|
||||
<button class='btn btn-danger' {{action "showSuspendModal" this}}>
|
||||
<i class='fa fa-ban'></i>
|
||||
{{fa-icon "ban"}}
|
||||
{{i18n 'admin.user.suspend'}}
|
||||
</button>
|
||||
{{i18n 'admin.user.suspended_explanation'}}
|
||||
@ -328,17 +327,17 @@
|
||||
</div>
|
||||
|
||||
{{#if isSuspended}}
|
||||
<div class='display-row highlight-danger'>
|
||||
<div class='field'>{{i18n 'admin.user.suspended_by'}}</div>
|
||||
<div class='value'>
|
||||
{{#link-to 'adminUser' suspendedBy}}{{avatar suspendedBy imageSize="tiny"}}{{/link-to}}
|
||||
{{#link-to 'adminUser' suspendedBy}}{{suspendedBy.username}}{{/link-to}}
|
||||
<div class='display-row highlight-danger'>
|
||||
<div class='field'>{{i18n 'admin.user.suspended_by'}}</div>
|
||||
<div class='value'>
|
||||
{{#link-to 'adminUser' suspendedBy}}{{avatar suspendedBy imageSize="tiny"}}{{/link-to}}
|
||||
{{#link-to 'adminUser' suspendedBy}}{{suspendedBy.username}}{{/link-to}}
|
||||
</div>
|
||||
<div class='controls'>
|
||||
<b>{{i18n 'admin.user.suspend_reason'}}</b>:
|
||||
{{suspend_reason}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='controls'>
|
||||
<b>{{i18n 'admin.user.suspend_reason'}}</b>:
|
||||
{{suspend_reason}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class='display-row' {{bind-attr class=":display-row blocked:highlight-danger"}}>
|
||||
@ -347,7 +346,7 @@
|
||||
<div class='controls'>
|
||||
{{#if blocked}}
|
||||
<button class='btn' {{action "unblock" target="content"}}>
|
||||
<i class='fa fa-thumbs-o-up'></i>
|
||||
{{fa-icon "thumbs-o-up"}}
|
||||
{{i18n 'admin.user.unblock'}}
|
||||
</button>
|
||||
{{i18n 'admin.user.block_explanation'}}
|
||||
@ -386,7 +385,7 @@
|
||||
{{#if can_delete_all_posts}}
|
||||
{{#if post_count}}
|
||||
<button class='btn btn-danger' {{action "deleteAllPosts" target="content"}}>
|
||||
<i class='fa fa-trash-o'></i>
|
||||
{{fa-icon "trash-o"}}
|
||||
{{i18n 'admin.user.delete_all_posts'}}
|
||||
</button>
|
||||
{{/if}}
|
||||
@ -473,7 +472,9 @@
|
||||
{{#if deleteExplanation}}
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<div class="pull-right"><i class="fa fa-exclamation-triangle"></i> {{deleteExplanation}}</div>
|
||||
<div class="pull-right">
|
||||
{{fa-icon "exclamation-triangle"}} {{deleteExplanation}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
<div class="clearfix"></div>
|
||||
|
@ -1683,6 +1683,10 @@ en:
|
||||
automatic: "Automatic"
|
||||
automatic_membership_email_domains: "Users who register with an email domain that exactly matches one in this list will be automatically added to this group:"
|
||||
automatic_membership_retroactive: "Apply the same email domain rule to add existing registered users"
|
||||
custom:
|
||||
title: "Custom Groups"
|
||||
automatic:
|
||||
title: "Automatic Groups"
|
||||
|
||||
api:
|
||||
generate_master: "Generate Master API Key"
|
||||
|
Loading…
x
Reference in New Issue
Block a user