UX: user preferences allows users to choose which title to use from their badges and groups

This commit is contained in:
Neil Lalonde 2018-04-06 14:29:27 -04:00
parent 10dad5de63
commit f6cfff3cea
7 changed files with 76 additions and 9 deletions

View File

@ -7,12 +7,13 @@ import { popupAjaxError } from 'discourse/lib/ajax-error';
export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController, {
saveAttrNames: ['name'],
saveAttrNames: ['name', 'title'],
canEditName: setting('enable_names'),
canSaveUser: true,
newNameInput: null,
newTitleInput: null,
passwordProgress: null,
@ -30,9 +31,9 @@ export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController,
return I18n.t(this.siteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions');
},
@computed("model.has_title_badges")
canSelectTitle(hasTitleBadges) {
return this.siteSettings.enable_badges && hasTitleBadges;
@computed('model.availableTitles')
canSelectTitle(availableTitles) {
return availableTitles.length > 0;
},
@computed()
@ -52,6 +53,7 @@ export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController,
const model = this.get('model');
model.set('name', this.get('newNameInput'));
model.set('title', this.get('newTitleInput'));
return model.save(this.get('saveAttrNames')).then(() => {
this.set('saved', true);

View File

@ -218,6 +218,7 @@ const User = RestModel.extend({
'website',
'location',
'name',
'title',
'locale',
'custom_fields',
'user_fields',
@ -569,6 +570,25 @@ const User = RestModel.extend({
canManageGroup(group) {
return group.get('automatic') ? false : (this.get('admin') || group.get('is_group_owner'));
},
@computed('groups.@each.title', 'badges.@each')
availableTitles() {
let titles = [];
_.each(this.get('groups'), group => {
if (group.get('title')) {
titles.push(group.get('title'));
}
});
_.each(this.get('badges'), badge => {
if (badge.get('allow_title')) {
titles.push(badge.get('name'));
}
});
return titles;
}
});

View File

@ -1,13 +1,23 @@
import UserBadge from 'discourse/models/user-badge';
import RestrictedUserRoute from "discourse/routes/restricted-user";
export default RestrictedUserRoute.extend({
showFooter: true,
model: function() {
const user = this.modelFor('user');
return UserBadge.findByUsername(this.modelFor('user').get('username')).then(userBadges => {
user.set('badges', userBadges.map(ub => ub.badge));
return user;
});
},
setupController(controller, user) {
controller.reset();
controller.setProperties({
model: user,
newNameInput: user.get('name')
newNameInput: user.get('name'),
newTitleInput: user.get('title')
});
}
});

View File

@ -100,8 +100,10 @@
<div class="control-group pref-title">
<label class="control-label">{{i18n 'user.title.title'}}</label>
<div class="controls">
<span class="static">{{model.title}}</span>
{{#link-to "preferences.badgeTitle" class="btn btn-small btn-icon pad-left no-text"}}{{d-icon "pencil"}}{{/link-to}}
{{combo-box
value=newTitleInput
content=model.availableTitles
none="user.title.none"}}
</div>
</div>
{{/if}}

View File

@ -1014,6 +1014,7 @@ en:
header_title: "profile, messages, bookmarks and preferences"
title:
title: "Title"
none: "(none)"
filters:
all: "All"

View File

@ -215,8 +215,11 @@ class Guardian
can_administer?(user) && !user.moderator?
end
def can_grant_title?(user)
user && is_staff?
def can_grant_title?(user, title = nil)
return true if user && is_staff?
return false if user != @user
return true if user.badges.where(name: title, allow_title: true).exists?
user.groups.where(title: title).exists?
end
def can_change_primary_group?(user)

View File

@ -2186,6 +2186,35 @@ describe Guardian do
it 'is false without a user to look at' do
expect(Guardian.new(admin).can_grant_title?(nil)).to be_falsey
end
context 'with title argument' do
let(:title_badge) { Fabricate(:badge, name: 'Helper', allow_title: true) }
let(:no_title_badge) { Fabricate(:badge, name: 'Writer', allow_title: false) }
let(:group) { Fabricate(:group, title: 'Groupie') }
it 'returns true if title belongs to a badge that user has' do
BadgeGranter.grant(title_badge, user)
expect(Guardian.new(user).can_grant_title?(user, title_badge.name)).to eq(true)
end
it "returns false if title belongs to a badge that user doesn't have" do
expect(Guardian.new(user).can_grant_title?(user, title_badge.name)).to eq(false)
end
it "returns false if title belongs to a badge that user has but can't be used as a title" do
BadgeGranter.grant(no_title_badge, user)
expect(Guardian.new(user).can_grant_title?(user, no_title_badge.name)).to eq(false)
end
it 'returns true if title is from a group the user belongs to' do
group.add(user)
expect(Guardian.new(user).can_grant_title?(user, group.title)).to eq(true)
end
it "returns false if title is from a group the user doesn't belong to" do
expect(Guardian.new(user).can_grant_title?(user, group.title)).to eq(false)
end
end
end
describe 'can_change_trust_level?' do