diff --git a/app/assets/javascripts/admin/controllers/admin_user_controller.js b/app/assets/javascripts/admin/controllers/admin_user_controller.js index 2565b8c8f59..cefbe0a3c61 100644 --- a/app/assets/javascripts/admin/controllers/admin_user_controller.js +++ b/app/assets/javascripts/admin/controllers/admin_user_controller.js @@ -6,4 +6,21 @@ @namespace Discourse @module Discourse **/ -Discourse.AdminUserController = Discourse.ObjectController.extend({}); \ No newline at end of file +Discourse.AdminUserController = Discourse.ObjectController.extend({ + editingTitle: false, + + toggleTitleEdit: function() { + this.set('editingTitle', !this.editingTitle); + }, + + saveTitle: function() { + Discourse.ajax("/users/" + this.get('username').toLowerCase(), { + data: {title: this.get('title')}, + type: 'PUT' + }).then(null, function(e){ + bootbox.alert(Em.String.i18n("generic_error_with_reason", {error: "http: " + e.status + " - " + e.body})); + }); + + this.toggleTitleEdit(); + } +}); \ No newline at end of file diff --git a/app/assets/javascripts/admin/templates/user.js.handlebars b/app/assets/javascripts/admin/templates/user.js.handlebars index 06e6591db06..fbad6ba1996 100644 --- a/app/assets/javascripts/admin/templates/user.js.handlebars +++ b/app/assets/javascripts/admin/templates/user.js.handlebars @@ -27,6 +27,25 @@
{{avatar content imageSize="large"}}
+
+
{{i18n user.title.title}}
+
+ {{#if editingTitle}} + {{textField value=title autofocus="autofocus"}} + {{else}} + {{title}}  + {{/if}} +
+
+ {{#if editingTitle}} + + Cancel + {{else}} + + {{/if}} +
+
+
{{i18n user.ip_address.title}}
{{ip_address}}
diff --git a/app/assets/javascripts/discourse/templates/post.js.handlebars b/app/assets/javascripts/discourse/templates/post.js.handlebars index 61e668397d0..b83ec83d531 100644 --- a/app/assets/javascripts/discourse/templates/post.js.handlebars +++ b/app/assets/javascripts/discourse/templates/post.js.handlebars @@ -28,6 +28,7 @@
{{avatar this imageSize="large"}}

{{breakUp username}}

+ {{#if user_title}}
{{user_title}}
{{/if}}
diff --git a/app/assets/stylesheets/application/topic-post.css.scss b/app/assets/stylesheets/application/topic-post.css.scss index dac676909fb..7484291812a 100644 --- a/app/assets/stylesheets/application/topic-post.css.scss +++ b/app/assets/stylesheets/application/topic-post.css.scss @@ -370,6 +370,16 @@ .score { font-size: 12px; } + .user-title { + font-size: 12px; + padding: 0 3px; + background-color: #ddd; + border-radius: 5px; + margin-top: 2px; + border: solid 1px #ccc; + font-weight: bold; + color: #555; + } } } .reply-to-tab { diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 540ff2b1724..6c11b3faea3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -48,6 +48,7 @@ class UsersController < ApplicationController u.digest_after_days = params[:digest_after_days] || u.digest_after_days u.auto_track_topics_after_msecs = params[:auto_track_topics_after_msecs].to_i if params[:auto_track_topics_after_msecs] u.new_topic_duration_minutes = params[:new_topic_duration_minutes].to_i if params[:new_topic_duration_minutes] + u.title = params[:title] || u.title if guardian.can_grant_title?(u) [:email_digests, :email_direct, :email_private_messages, :external_links_in_new_tab, :enable_quoting, :dynamic_favicon].each do |i| diff --git a/app/serializers/admin_user_serializer.rb b/app/serializers/admin_user_serializer.rb index 8858f2bbde8..cb5860dfa7d 100644 --- a/app/serializers/admin_user_serializer.rb +++ b/app/serializers/admin_user_serializer.rb @@ -12,6 +12,7 @@ class AdminUserSerializer < BasicUserSerializer :trust_level, :flag_level, :username, + :title, :avatar_template, :topics_entered, :posts_read_count, diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb index c0c00479bcf..2270642c82d 100644 --- a/app/serializers/post_serializer.rb +++ b/app/serializers/post_serializer.rb @@ -33,6 +33,7 @@ class PostSerializer < ApplicationSerializer :read, :username, :name, + :user_title, :reply_to_user, :bookmarked, :raw, @@ -128,6 +129,10 @@ class PostSerializer < ApplicationSerializer object.user.name end + def user_title + object.user.title + end + def trust_level object.user.trust_level end diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index e1224bcf2d0..598b67a03aa 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -14,7 +14,8 @@ class UserSerializer < BasicUserSerializer :bio_excerpt, :trust_level, :moderator, - :admin + :admin, + :title has_one :invited_by, embed: :object, serializer: BasicUserSerializer diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 790c7b41b30..27217d6dbd0 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -78,6 +78,7 @@ en: yes_value: "Yes" of_value: "of" generic_error: "Sorry, an error has occurred." + generic_error_with_reason: "An error occured: %{error}" log_in: "Log In" age: "Age" last_post: "Last Post" @@ -294,6 +295,8 @@ en: avatar: title: "Avatar" instructions: "We use Gravatar for avatars based on your email" + title: + title: "Title" filters: all: "All" @@ -1166,6 +1169,8 @@ en: admin: "Admin?" blocked: "Blocked?" show_admin_profile: "Admin" + edit_title: "Edit Title" + save_title: "Save Title" refresh_browsers: "Force browser refresh" show_public_profile: "Show Public Profile" impersonate: 'Impersonate' diff --git a/db/migrate/20130625201113_add_title_to_users.rb b/db/migrate/20130625201113_add_title_to_users.rb new file mode 100644 index 00000000000..8b921702a64 --- /dev/null +++ b/db/migrate/20130625201113_add_title_to_users.rb @@ -0,0 +1,5 @@ +class AddTitleToUsers < ActiveRecord::Migration + def change + add_column :users, :title, :string + end +end diff --git a/lib/guardian.rb b/lib/guardian.rb index e5046d5fd60..ed49762376b 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -133,6 +133,10 @@ class Guardian can_administer?(user) && not(user.moderator?) end + def can_grant_title?(user) + user && is_staff? + end + def can_block_user?(user) user && is_staff? && not(user.staff?) end diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index 05bc8b8b584..049a5966ea9 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -937,5 +937,27 @@ describe Guardian do end end + describe 'can_grant_title?' do + it 'is false without a logged in user' do + Guardian.new(nil).can_grant_title?(user).should be_false + end + + it 'is false for regular users' do + Guardian.new(user).can_grant_title?(user).should be_false + end + + it 'is true for moderators' do + Guardian.new(moderator).can_grant_title?(user).should be_true + end + + it 'is true for admins' do + Guardian.new(admin).can_grant_title?(user).should be_true + end + + it 'is false without a user to look at' do + Guardian.new(admin).can_grant_title?(nil).should be_false + end + end + end