mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
Merge pull request #2537 from ligthyear/group-member-management-on-user
Improved Group Member Management on User Administration
This commit is contained in:
commit
f06f8abedd
9 changed files with 103 additions and 9 deletions
|
@ -0,0 +1,34 @@
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
tagName: 'div',
|
||||||
|
|
||||||
|
didInsertElement: function(){
|
||||||
|
this.$("input").select2({
|
||||||
|
multiple: true,
|
||||||
|
width: '100%',
|
||||||
|
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)});
|
||||||
|
} else if (evt.removed) {
|
||||||
|
this.triggerAction({action:"groupRemoved",
|
||||||
|
actionContext: this.get("selected"
|
||||||
|
).findBy("id", evt.removed.id)});
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
this._refreshOnReset();
|
||||||
|
},
|
||||||
|
|
||||||
|
_format: function(item){
|
||||||
|
return {"text": item.name, "id": item.id, "locked": item.automatic};
|
||||||
|
},
|
||||||
|
|
||||||
|
_refreshOnReset: function() {
|
||||||
|
this.$("input").select2("data", this.get("selected").map(this._format));
|
||||||
|
}.observes("selected")
|
||||||
|
});
|
|
@ -25,6 +25,10 @@ Discourse.AdminUserIndexController = Discourse.ObjectController.extend({
|
||||||
|
|
||||||
primaryGroupDirty: Discourse.computed.propertyNotEqual('originalPrimaryGroupId', 'primary_group_id'),
|
primaryGroupDirty: Discourse.computed.propertyNotEqual('originalPrimaryGroupId', 'primary_group_id'),
|
||||||
|
|
||||||
|
custom_groups: Ember.computed.filter("model.groups", function(g){
|
||||||
|
return (!g.automatic && g.visible);
|
||||||
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
toggleTitleEdit: function() {
|
toggleTitleEdit: function() {
|
||||||
this.toggleProperty('editingTitle');
|
this.toggleProperty('editingTitle');
|
||||||
|
@ -45,6 +49,18 @@ Discourse.AdminUserIndexController = Discourse.ObjectController.extend({
|
||||||
this.get('model').generateApiKey();
|
this.get('model').generateApiKey();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
groupAdded: function(added){
|
||||||
|
this.get('model').groupAdded(added).catch(function() {
|
||||||
|
bootbox.alert(I18n.t('generic_error'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
groupRemoved: function(removed){
|
||||||
|
this.get('model').groupRemoved(removed).catch(function() {
|
||||||
|
bootbox.alert(I18n.t('generic_error'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
savePrimaryGroup: function() {
|
savePrimaryGroup: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", {
|
Discourse.ajax("/admin/users/" + this.get('id') + "/primary_group", {
|
||||||
|
|
|
@ -23,6 +23,25 @@ Discourse.AdminUser = Discourse.User.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
groupAdded: function(added){
|
||||||
|
var self = this;
|
||||||
|
return Discourse.ajax("/admin/users/" + this.get('id') + "/groups", {
|
||||||
|
type: 'POST',
|
||||||
|
data: {group_id: added.id}
|
||||||
|
}).then(function () {
|
||||||
|
self.get('groups').pushObject(added);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
groupRemoved: function(removed){
|
||||||
|
var self = this;
|
||||||
|
return Discourse.ajax("/admin/users/" + this.get('id') + "/groups/" + removed.id, {
|
||||||
|
type: 'DELETE'
|
||||||
|
}).then(function () {
|
||||||
|
self.set('groups.[]', self.get('groups').rejectBy("id", removed.id));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Revokes a user's current API key
|
Revokes a user's current API key
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,11 @@ Discourse.AdminUserRoute = Discourse.Route.extend({
|
||||||
afterModel: function(adminUser) {
|
afterModel: function(adminUser) {
|
||||||
var controller = this.controllerFor('adminUser');
|
var controller = this.controllerFor('adminUser');
|
||||||
|
|
||||||
|
Discourse.Group.findAll().then(function(groups){
|
||||||
|
controller.set("availableGroups", groups.filterBy("automatic", false));
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
|
||||||
return adminUser.loadDetails().then(function () {
|
return adminUser.loadDetails().then(function () {
|
||||||
adminUser.setOriginalTrustLevel();
|
adminUser.setOriginalTrustLevel();
|
||||||
controller.set('model', adminUser);
|
controller.set('model', adminUser);
|
||||||
|
|
|
@ -53,20 +53,18 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='display-row'>
|
<div class='display-row'>
|
||||||
<div class='field'>{{i18n admin.groups.primary}}</div>
|
<div class='field'>{{i18n admin.groups.title}}</div>
|
||||||
<div class='value'>
|
<div class='value'>
|
||||||
{{#if custom_groups}}
|
{{admin-group-selector selected=model.groups available=availableGroups}}
|
||||||
{{combo-box content=custom_groups value=primary_group_id nameProperty="name" none="admin.groups.no_primary"}}
|
|
||||||
{{else}}
|
|
||||||
—
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
<div class='controls'>
|
<div class='controls'>
|
||||||
|
{{#if custom_groups}}
|
||||||
|
{{i18n admin.groups.primary}}
|
||||||
|
{{combo-box content=custom_groups value=primary_group_id nameProperty="name" none="admin.groups.no_primary"}}
|
||||||
|
{{/if}}
|
||||||
{{#if primaryGroupDirty}}
|
{{#if primaryGroupDirty}}
|
||||||
<div>
|
|
||||||
<button class='btn ok no-text' {{action savePrimaryGroup}}><i class='fa fa-check'></i></button>
|
<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>
|
<button class='btn cancel no-text' {{action resetPrimaryGroup}}><i class='fa fa-times'></i></button>
|
||||||
</div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
<input type="text">
|
||||||
|
|
|
@ -17,6 +17,8 @@ class Admin::UsersController < Admin::AdminController
|
||||||
:block,
|
:block,
|
||||||
:unblock,
|
:unblock,
|
||||||
:trust_level,
|
:trust_level,
|
||||||
|
:add_group,
|
||||||
|
:remove_group,
|
||||||
:primary_group,
|
:primary_group,
|
||||||
:generate_api_key,
|
:generate_api_key,
|
||||||
:revoke_api_key]
|
:revoke_api_key]
|
||||||
|
@ -101,6 +103,21 @@ class Admin::UsersController < Admin::AdminController
|
||||||
render_serialized(@user, AdminUserSerializer)
|
render_serialized(@user, AdminUserSerializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_group
|
||||||
|
group = Group.find(params[:group_id].to_i)
|
||||||
|
return render_json_error group unless group && !group.automatic
|
||||||
|
group.users << @user
|
||||||
|
render nothing: true
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_group
|
||||||
|
group = Group.find(params[:group_id].to_i)
|
||||||
|
return render_json_error group unless group && !group.automatic
|
||||||
|
group.users.delete(@user)
|
||||||
|
render nothing: true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def primary_group
|
def primary_group
|
||||||
guardian.ensure_can_change_primary_group!(@user)
|
guardian.ensure_can_change_primary_group!(@user)
|
||||||
@user.primary_group_id = params[:primary_group_id]
|
@user.primary_group_id = params[:primary_group_id]
|
||||||
|
|
|
@ -22,7 +22,7 @@ class AdminDetailedUserSerializer < AdminUserSerializer
|
||||||
has_one :api_key, serializer: ApiKeySerializer, embed: :objects
|
has_one :api_key, serializer: ApiKeySerializer, embed: :objects
|
||||||
has_one :suspended_by, serializer: BasicUserSerializer, embed: :objects
|
has_one :suspended_by, serializer: BasicUserSerializer, embed: :objects
|
||||||
has_one :leader_requirements, serializer: LeaderRequirementsSerializer, embed: :objects
|
has_one :leader_requirements, serializer: LeaderRequirementsSerializer, embed: :objects
|
||||||
has_many :custom_groups, embed: :object, serializer: BasicGroupSerializer
|
has_many :groups, embed: :object, serializer: BasicGroupSerializer
|
||||||
|
|
||||||
def can_revoke_admin
|
def can_revoke_admin
|
||||||
scope.can_revoke_admin?(object)
|
scope.can_revoke_admin?(object)
|
||||||
|
|
|
@ -70,6 +70,8 @@ Discourse::Application.routes.draw do
|
||||||
put "unblock"
|
put "unblock"
|
||||||
put "trust_level"
|
put "trust_level"
|
||||||
put "primary_group"
|
put "primary_group"
|
||||||
|
post "groups" => "users#add_group", constraints: AdminConstraint.new
|
||||||
|
delete "groups/:group_id" => "users#remove_group", constraints: AdminConstraint.new
|
||||||
get "badges"
|
get "badges"
|
||||||
get "leader_requirements"
|
get "leader_requirements"
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue