mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Interface for granting/revoking badges from admin user page.
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
This controller supports the interface for granting and revoking badges from
|
||||
individual users.
|
||||
|
||||
@class AdminUserBadgesController
|
||||
@extends Ember.ArrayController
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminUserBadgesController = Ember.ArrayController.extend({
|
||||
needs: ["adminUser"],
|
||||
user: Em.computed.alias('controllers.adminUser'),
|
||||
sortProperties: ['granted_at'],
|
||||
sortAscending: false,
|
||||
|
||||
actions: {
|
||||
|
||||
/**
|
||||
Grant the selected badge to the user.
|
||||
|
||||
@method grantBadge
|
||||
@param {Integer} badgeId id of the badge we want to grant.
|
||||
**/
|
||||
grantBadge: function(badgeId) {
|
||||
var self = this;
|
||||
Discourse.UserBadge.grant(badgeId, this.get('user.username')).then(function(userBadge) {
|
||||
self.pushObject(userBadge);
|
||||
}, function() {
|
||||
// Failure
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Revoke the selected userBadge.
|
||||
|
||||
@method revokeBadge
|
||||
@param {Discourse.UserBadge} userBadge the `Discourse.UserBadge` instance that needs to be revoked.
|
||||
**/
|
||||
revokeBadge: function(userBadge) {
|
||||
var self = this;
|
||||
return bootbox.confirm(I18n.t("admin.badges.revoke_confirm"), I18n.t("no_value"), I18n.t("yes_value"), function(result) {
|
||||
if (result) {
|
||||
userBadge.revoke().then(function() {
|
||||
self.get('model').removeObject(userBadge);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
@@ -47,6 +47,7 @@ Discourse.Route.buildRoutes(function() {
|
||||
|
||||
this.resource('adminUsers', { path: '/users' }, function() {
|
||||
this.resource('adminUser', { path: '/:username' }, function() {
|
||||
this.route('badges');
|
||||
this.route('leaderRequirements', { path: '/leader_requirements' });
|
||||
});
|
||||
this.resource('adminUsersList', { path: '/list' }, function() {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
Shows all of the badges that have been granted to a user, and allow granting and
|
||||
revoking badges.
|
||||
|
||||
@class AdminUserBadgesRoute
|
||||
@extends Discourse.Route
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AdminUserBadgesRoute = Discourse.Route.extend({
|
||||
model: function() {
|
||||
var username = this.controllerFor('adminUser').get('username');
|
||||
return Discourse.UserBadge.findByUsername(username);
|
||||
},
|
||||
|
||||
setupController: function(controller, model) {
|
||||
// Find all badges.
|
||||
controller.set('loading', true);
|
||||
Discourse.Badge.findAll().then(function(badges) {
|
||||
controller.set('badges', badges);
|
||||
if (badges.length > 0) {
|
||||
controller.set('selectedBadgeId', badges[0].get('id'));
|
||||
} else {
|
||||
controller.set('noBadges', true);
|
||||
}
|
||||
controller.set('loading', false);
|
||||
});
|
||||
// Set the model.
|
||||
controller.set('model', model);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
<div class='admin-controls'>
|
||||
<div class='span15'>
|
||||
<ul class='nav nav-pills'>
|
||||
<li>{{#link-to 'adminUser' user}}<i class="fa fa-caret-left"></i> {{user.username}}{{/link-to}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if loading}}
|
||||
<div class='spinner'>{{i18n loading}}</div>
|
||||
{{else}}
|
||||
<div class='admin-container user-badges'>
|
||||
<h2>{{i18n admin.badges.grant_badge}}</h2>
|
||||
{{#if noBadges}}
|
||||
<p>{{i18n admin.badges.no_badges}}</p>
|
||||
{{else}}
|
||||
<br>
|
||||
{{combobox valueAttribute="id" value=controller.selectedBadgeId content=controller.badges}}
|
||||
<button class='btn btn-primary' {{action grantBadge controller.selectedBadgeId}}>{{i18n admin.badges.grant}}</button>
|
||||
{{/if}}
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<h2>{{i18n admin.badges.granted_badges}}</h2>
|
||||
<br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>{{i18n admin.badges.name}}</th>
|
||||
<th>{{i18n admin.badges.badge_type}}</th>
|
||||
<th>{{i18n admin.badges.granted_by}}</th>
|
||||
<th>{{i18n admin.badges.granted_at}}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
{{#each}}
|
||||
<tr>
|
||||
<td>{{badge.displayName}}</td>
|
||||
<td>{{badge.badge_type.name}}</td>
|
||||
<td>
|
||||
{{#link-to 'adminUser' badge.granted_by}}
|
||||
{{avatar granted_by imageSize="tiny"}}
|
||||
{{granted_by.username}}
|
||||
{{/link-to}}
|
||||
</td>
|
||||
<td>{{unboundAgeWithTooltip granted_at}}</td>
|
||||
<td>
|
||||
<button class='btn' {{action revokeBadge this}}>{{i18n admin.badges.revoke}}</button>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<p>{{i18n admin.badges.no_user_badges name=user.username}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -77,6 +77,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if showBadges}}
|
||||
<div class='display-row'>
|
||||
<div class='field'>{{i18n admin.badges.title}}</div>
|
||||
<div class='value'>
|
||||
TODO featured badges
|
||||
</div>
|
||||
<div class='controls'>
|
||||
{{#link-to 'adminUser.badges' this class="btn"}}{{i18n admin.badges.edit_badges}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
@@ -336,12 +348,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{#if showBadges}}
|
||||
<section class='details'>
|
||||
<h1>{{i18n admin.badges.title}}</h1>
|
||||
</section>
|
||||
{{/if}}
|
||||
|
||||
<section>
|
||||
<hr/>
|
||||
<button {{bind-attr class=":btn :btn-danger :pull-right deleteForbidden:hidden"}} {{action destroy target="content"}} {{bind-attr disabled="deleteForbidden"}}>
|
||||
|
||||
@@ -7,6 +7,17 @@
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.UserBadge = Discourse.Model.extend({
|
||||
/**
|
||||
Revoke this badge.
|
||||
|
||||
@method revoke
|
||||
@returns {Promise} a promise that resolves when the badge has been revoked.
|
||||
**/
|
||||
revoke: function() {
|
||||
return Discourse.ajax("/user_badges/" + this.get('id'), {
|
||||
type: "DELETE"
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Discourse.UserBadge.reopenClass({
|
||||
@@ -19,14 +30,15 @@ Discourse.UserBadge.reopenClass({
|
||||
**/
|
||||
createFromJson: function(json) {
|
||||
// Create User objects.
|
||||
if (json.users === undefined) { json.users = []; }
|
||||
var users = {};
|
||||
json.users.forEach(function(userJson) {
|
||||
users[userJson.id] = Discourse.User.create(userJson);
|
||||
});
|
||||
|
||||
// Create the badges.
|
||||
if (json.badges === undefined) { json.badges = []; }
|
||||
var badges = {};
|
||||
|
||||
Discourse.Badge.createFromJson(json).forEach(function(badge) {
|
||||
badges[badge.get('id')] = badge;
|
||||
});
|
||||
@@ -53,5 +65,37 @@ Discourse.UserBadge.reopenClass({
|
||||
} else {
|
||||
return userBadges;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Find all badges for a given username.
|
||||
|
||||
@method findByUsername
|
||||
@returns {Promise} a promise that resolves to an array of `Discourse.UserBadge`.
|
||||
**/
|
||||
findByUsername: function(username) {
|
||||
return Discourse.ajax("/user_badges.json?username=" + username).then(function(json) {
|
||||
return Discourse.UserBadge.createFromJson(json);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Grant the badge having id `badgeId` to the user identified by `username`.
|
||||
|
||||
@method grant
|
||||
@param {Integer} badgeId id of the badge to be granted.
|
||||
@param {String} username username of the user to be granted the badge.
|
||||
@returns {Promise} a promise that resolves to an instance of `Discourse.UserBadge`.
|
||||
**/
|
||||
grant: function(badgeId, username) {
|
||||
return Discourse.ajax("/user_badges", {
|
||||
type: "POST",
|
||||
data: {
|
||||
username: username,
|
||||
badge_id: badgeId
|
||||
}
|
||||
}).then(function(json) {
|
||||
return Discourse.UserBadge.createFromJson(json);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -169,6 +169,9 @@ class Admin::UsersController < Admin::AdminController
|
||||
end
|
||||
end
|
||||
|
||||
def badges
|
||||
end
|
||||
|
||||
def leader_requirements
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user