Let's not show tons of extra information about invites unless you're the

person who invited them.
This commit is contained in:
Robin Ward 2014-03-21 14:13:04 -04:00
parent e7ae0bba5f
commit 539890afdf
9 changed files with 89 additions and 50 deletions

View file

@ -6,7 +6,13 @@
@namespace Discourse @namespace Discourse
@module Discourse @module Discourse
**/ **/
Discourse.UserInvitedController = Ember.ArrayController.extend({ Discourse.UserInvitedController = Ember.ObjectController.extend({
user: null,
init: function() {
this._super();
this.set('searchTerm', '');
},
/** /**
Observe the search term box with a debouncer and change the results. Observe the search term box with a debouncer and change the results.
@ -44,8 +50,8 @@ Discourse.UserInvitedController = Ember.ArrayController.extend({
@property showSearch @property showSearch
**/ **/
showSearch: function() { showSearch: function() {
return !(Em.isNone(this.get('searchTerm')) && this.get('model.length') === 0); return !(Em.isNone(this.get('searchTerm')) && this.get('invites.length') === 0);
}.property('searchTerm', 'model.length'), }.property('searchTerm', 'invites.length'),
/** /**
Were the results limited by our `maxInvites` Were the results limited by our `maxInvites`
@ -53,8 +59,8 @@ Discourse.UserInvitedController = Ember.ArrayController.extend({
@property truncated @property truncated
**/ **/
truncated: function() { truncated: function() {
return this.get('model.length') === Discourse.SiteSettings.invites_shown; return this.get('invites.length') === Discourse.SiteSettings.invites_shown;
}.property('model.length'), }.property('invites.length'),
actions: { actions: {

View file

@ -36,9 +36,11 @@ Discourse.Invite.reopenClass({
if (!Em.isNone(filter)) { data.filter = filter; } if (!Em.isNone(filter)) { data.filter = filter; }
return Discourse.ajax("/users/" + user.get('username_lower') + "/invited.json", {data: data}).then(function (result) { return Discourse.ajax("/users/" + user.get('username_lower') + "/invited.json", {data: data}).then(function (result) {
return result.map(function (i) { result.invites = result.invites.map(function (i) {
return Discourse.Invite.create(i); return Discourse.Invite.create(i);
}); });
return Em.Object.create(result);
}); });
} }

View file

@ -12,42 +12,46 @@
</form> </form>
{{/if}} {{/if}}
{{#if model}} {{#if model.invites}}
<table class='table'> <table class='table'>
<tr> <tr>
<th>{{i18n user.invited.user}}</th> <th>{{i18n user.invited.user}}</th>
<th>{{i18n user.invited.redeemed_at}}</th> <th>{{i18n user.invited.redeemed_at}}</th>
<th>{{i18n user.last_seen}}</th> {{#if can_see_invite_details}}
<th>{{i18n user.invited.topics_entered}}</th> <th>{{i18n user.last_seen}}</th>
<th>{{i18n user.invited.posts_read_count}}</th> <th>{{i18n user.invited.topics_entered}}</th>
<th>{{i18n user.invited.time_read}}</th> <th>{{i18n user.invited.posts_read_count}}</th>
<th>{{i18n user.invited.days_visited}}</th> <th>{{i18n user.invited.time_read}}</th>
<th>{{i18n user.invited.days_visited}}</th>
{{/if}}
</tr> </tr>
{{#each model}} {{#each invite in model.invites}}
<tr> <tr>
{{#if user}} {{#if invite.user}}
<td> <td>
{{#link-to 'user' user}}{{avatar user imageSize="tiny"}}{{/link-to}} {{#link-to 'user' invite.user}}{{avatar invite.user imageSize="tiny"}}{{/link-to}}
{{#link-to 'user' user}}{{user.username}}{{/link-to}} {{#link-to 'user' invite.user}}{{invite.user.username}}{{/link-to}}
</td> </td>
<td>{{unboundDate redeemed_at}}</td> <td>{{unboundDate invite.redeemed_at}}</td>
<td>{{unboundDate user.last_seen_at}}</td> {{#if can_see_invite_details}}
<td>{{number user.topics_entered}}</td> <td>{{unboundDate invite.user.last_seen_at}}</td>
<td>{{number user.posts_read_count}}</td> <td>{{number invite.user.topics_entered}}</td>
<td>{{{unbound user.time_read}}}</td> <td>{{number invite.user.posts_read_count}}</td>
<td><span title="{{i18n user.invited.days_visited}}">{{{unbound user.days_visited}}}</span> <td>{{{unbound invite.user.time_read}}}</td>
/ <td><span title="{{i18n user.invited.days_visited}}">{{{unbound invite.user.days_visited}}}</span>
<span title="{{i18n user.invited.account_age_days}}">{{{unbound user.days_since_created}}}</span></td> /
<span title="{{i18n user.invited.account_age_days}}">{{{unbound invite.user.days_since_created}}}</span></td>
{{/if}}
{{else}} {{else}}
<td>{{unbound email}}</td> <td>{{unbound invite.email}}</td>
<td colspan='6'> <td colspan='6'>
{{#if expired}} {{#if invite.expired}}
{{i18n user.invited.expired}} {{i18n user.invited.expired}}
{{/if}} {{/if}}
{{#if rescinded}} {{#if invite.rescinded}}
{{i18n user.invited.rescinded}} {{i18n user.invited.rescinded}}
{{else}} {{else}}
<button class='btn' {{action rescind this}}>{{i18n user.invited.rescind}}</button> <button class='btn' {{action rescind invite}}>{{i18n user.invited.rescind}}</button>
{{/if}} {{/if}}
</td> </td>
{{/if}} {{/if}}

View file

@ -68,15 +68,15 @@ class UsersController < ApplicationController
def invited def invited
inviter = fetch_user_from_params inviter = fetch_user_from_params
invites = if guardian.can_see_pending_invites_from?(inviter) invites = if guardian.can_see_invite_details?(inviter)
Invite.find_all_invites_from(inviter) Invite.find_all_invites_from(inviter)
else else
Invite.find_redeemed_invites_from(inviter) Invite.find_redeemed_invites_from(inviter)
end end
invites = invites.filter_by(params[:filter]) invites = invites.filter_by(params[:filter])
render_json_dump invites: serialize_data(invites.to_a, InviteSerializer),
render_serialized(invites.to_a, InviteSerializer) can_see_invite_details: guardian.can_see_invite_details?(inviter)
end end
def is_local_username def is_local_username

View file

@ -1,7 +1,6 @@
class InviteSerializer < ApplicationSerializer class InviteSerializer < ApplicationSerializer
attributes :email, :created_at, :redeemed_at, :expired attributes :email, :created_at, :redeemed_at, :expired, :user
has_one :user, embed: :objects, serializer: InvitedUserSerializer
def include_email? def include_email?
!object.redeemed? !object.redeemed?
@ -11,4 +10,10 @@ class InviteSerializer < ApplicationSerializer
object.expired? object.expired?
end end
def user
ser = InvitedUserSerializer.new(object.user, scope: scope, root: false)
ser.invited_by = object.invited_by
ser.as_json
end
end end

View file

@ -7,24 +7,46 @@ class InvitedUserSerializer < BasicUserSerializer
:days_visited, :days_visited,
:days_since_created :days_since_created
attr_accessor :invited_by
def time_read def time_read
AgeWords.age_words(object.user_stat.time_read) AgeWords.age_words(object.user_stat.time_read)
end end
def include_time_read?
scope.can_see_invite_details?(invited_by)
end
def days_visited def days_visited
object.user_stat.days_visited object.user_stat.days_visited
end end
def include_days_visited?
scope.can_see_invite_details?(invited_by)
end
def topics_entered def topics_entered
object.user_stat.topics_entered object.user_stat.topics_entered
end end
def include_topics_entered?
scope.can_see_invite_details?(invited_by)
end
def posts_read_count def posts_read_count
object.user_stat.posts_read_count object.user_stat.posts_read_count
end end
def include_posts_read_count?
scope.can_see_invite_details?(invited_by)
end
def days_since_created def days_since_created
((Time.now - object.created_at) / 60 / 60 / 24).ceil ((Time.now - object.created_at) / 60 / 60 / 24).ceil
end end
def include_days_since_created
scope.can_see_invite_details?(invited_by)
end
end end

View file

@ -176,7 +176,7 @@ class Guardian
@user.approved? @user.approved?
end end
def can_see_pending_invites_from?(user) def can_see_invite_details?(user)
is_me?(user) is_me?(user)
end end

View file

@ -1108,18 +1108,18 @@ describe Guardian do
end end
end end
context "can_see_pending_invites_from?" do context "can_see_invite_details?" do
it 'is false without a logged in user' do it 'is false without a logged in user' do
Guardian.new(nil).can_see_pending_invites_from?(user).should be_false Guardian.new(nil).can_see_invite_details?(user).should be_false
end end
it 'is false without a user to look at' do it 'is false without a user to look at' do
Guardian.new(user).can_see_pending_invites_from?(nil).should be_false Guardian.new(user).can_see_invite_details?(nil).should be_false
end end
it 'is true when looking at your own invites' do it 'is true when looking at your own invites' do
Guardian.new(user).can_see_pending_invites_from?(user).should be_true Guardian.new(user).can_see_invite_details?(user).should be_true
end end
end end

View file

@ -835,7 +835,7 @@ describe UsersController do
xhr :get, :invited, username: inviter.username, filter: 'billybob' xhr :get, :invited, username: inviter.username, filter: 'billybob'
invites = JSON.parse(response.body) invites = JSON.parse(response.body)['invites']
expect(invites).to have(1).item expect(invites).to have(1).item
expect(invites.first).to include('email' => 'billybob@example.com') expect(invites.first).to include('email' => 'billybob@example.com')
end end
@ -857,7 +857,7 @@ describe UsersController do
xhr :get, :invited, username: inviter.username, filter: 'billybob' xhr :get, :invited, username: inviter.username, filter: 'billybob'
invites = JSON.parse(response.body) invites = JSON.parse(response.body)['invites']
expect(invites).to have(1).item expect(invites).to have(1).item
expect(invites.first).to include('email' => 'billybob@example.com') expect(invites.first).to include('email' => 'billybob@example.com')
end end
@ -870,7 +870,7 @@ describe UsersController do
xhr :get, :invited, username: inviter.username xhr :get, :invited, username: inviter.username
invites = JSON.parse(response.body) invites = JSON.parse(response.body)['invites']
expect(invites).to be_empty expect(invites).to be_empty
end end
end end
@ -883,7 +883,7 @@ describe UsersController do
xhr :get, :invited, username: inviter.username xhr :get, :invited, username: inviter.username
invites = JSON.parse(response.body) invites = JSON.parse(response.body)['invites']
expect(invites).to have(1).item expect(invites).to have(1).item
expect(invites.first).to include('email' => invite.email) expect(invites.first).to include('email' => invite.email)
end end
@ -898,13 +898,13 @@ describe UsersController do
inviter = Fabricate(:user) inviter = Fabricate(:user)
invite = Fabricate(:invite, invited_by: inviter) invite = Fabricate(:invite, invited_by: inviter)
stub_guardian(user) do |guardian| stub_guardian(user) do |guardian|
guardian.stubs(:can_see_pending_invites_from?). guardian.stubs(:can_see_invite_details?).
with(inviter).returns(true) with(inviter).returns(true)
end end
xhr :get, :invited, username: inviter.username xhr :get, :invited, username: inviter.username
invites = JSON.parse(response.body) invites = JSON.parse(response.body)['invites']
expect(invites).to have(1).item expect(invites).to have(1).item
expect(invites.first).to include("email" => invite.email) expect(invites.first).to include("email" => invite.email)
end end
@ -917,14 +917,14 @@ describe UsersController do
invitee = Fabricate(:user) invitee = Fabricate(:user)
Fabricate(:invite, invited_by: inviter) Fabricate(:invite, invited_by: inviter)
stub_guardian(user) do |guardian| stub_guardian(user) do |guardian|
guardian.stubs(:can_see_pending_invites_from?). guardian.stubs(:can_see_invite_details?).
with(inviter).returns(false) with(inviter).returns(false)
end end
xhr :get, :invited, username: inviter.username xhr :get, :invited, username: inviter.username
invites = JSON.parse(response.body) json = JSON.parse(response.body)['invites']
expect(invites).to be_empty expect(json).to be_empty
end end
end end
end end
@ -938,7 +938,7 @@ describe UsersController do
xhr :get, :invited, username: inviter.username xhr :get, :invited, username: inviter.username
invites = JSON.parse(response.body) invites = JSON.parse(response.body)['invites']
expect(invites).to have(1).item expect(invites).to have(1).item
expect(invites.first).to include('email' => invite.email) expect(invites.first).to include('email' => invite.email)
end end