Commit ad29f61a1c2b2cbba9c6be601d5a3533c71fc472

Authored by Daniela Feitosa
1 parent 495f736d

[suggestions] Displays categories in common

(ActionItem3234)
app/controllers/my_profile/friends_controller.rb
... ... @@ -3,7 +3,7 @@ class FriendsController < MyProfileController
3 3 protect 'manage_friends', :profile
4 4  
5 5 def index
6   - @suggestions = profile.suggested_people.limit(per_page/2)
  6 + @suggestions = profile.profile_suggestions.of_person.includes(:suggestion).limit(per_page)
7 7 if is_cache_expired?(profile.manage_friends_cache_key(params))
8 8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage])
9 9 end
... ... @@ -18,17 +18,15 @@ class FriendsController < MyProfileController
18 18 end
19 19  
20 20 def suggest
21   - @suggestions = profile.suggested_people.paginate(:per_page => per_page, :page => params[:npage])
  21 + @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page)
22 22 end
23 23  
24 24 def remove_suggestion
25 25 @person = profile.suggested_people.find_by_identifier(params[:id])
26 26 redirect_to :action => 'suggest' unless @person
27 27 if @person && request.post?
28   - suggestion = profile.profile_suggestions.find_by_suggestion_id @person.id
29   - suggestion.disable
  28 + profile.remove_suggestion(@person)
30 29 session[:notice] = _('Suggestion removed')
31   - redirect_to :action => 'suggest'
32 30 end
33 31 end
34 32  
... ...
app/controllers/my_profile/memberships_controller.rb
... ... @@ -40,7 +40,7 @@ class MembershipsController < MyProfileController
40 40 end
41 41  
42 42 def suggest
43   - @suggestions = profile.suggested_communities.paginate(:per_page => 8, :page => params[:npage])
  43 + @suggestions = profile.profile_suggestions.of_community.includes(:suggestion).limit(per_page)
44 44 end
45 45  
46 46 def remove_suggestion
... ... @@ -53,4 +53,10 @@ class MembershipsController < MyProfileController
53 53 end
54 54 end
55 55  
  56 + protected
  57 +
  58 + def per_page
  59 + 10
  60 + end
  61 +
56 62 end
... ...
app/helpers/application_helper.rb
... ... @@ -1419,4 +1419,9 @@ module ApplicationHelper
1419 1419 text_field_tag name, default, options.merge({:id => 'search-input', 'data-asset' => asset})
1420 1420 end
1421 1421  
  1422 + def profile_suggestion_categories(suggestion)
  1423 + suggestion.categories.map do |cat|
  1424 + content_tag(:p, content_tag(:span, "#{suggestion.category_label(cat[0])}: #{cat[1]}", :class => suggestion.category_icon(cat[0])))
  1425 + end.join
  1426 + end
1422 1427 end
... ...
app/mailers/user_mailer.rb
... ... @@ -54,7 +54,7 @@ class UserMailer < ActionMailer::Base
54 54 content_type: 'text/html',
55 55 to: user.email,
56 56 from: "#{user.environment.name} <#{user.environment.contact_email}>",
57   - subject: _("[%s] We have suggestions for your network") % user.environment.name
  57 + subject: _("[%s] What about grow up your network?") % user.environment.name
58 58 )
59 59 end
60 60  
... ...
app/models/person.rb
... ... @@ -66,7 +66,7 @@ class Person &lt; Profile
66 66 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
67 67 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
68 68  
69   - has_many :profile_suggestions, :foreign_key => :person_id, :dependent => :destroy
  69 + has_many :profile_suggestions, :foreign_key => :person_id, :order => 'id ASC', :dependent => :destroy
70 70 has_many :suggested_people, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]
71 71 has_many :suggested_communities, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true]
72 72  
... ... @@ -498,6 +498,11 @@ class Person &lt; Profile
498 498 person.notifier.reschedule_next_notification_mail
499 499 end
500 500  
  501 + def remove_suggestion(profile)
  502 + suggestion = profile_suggestions.find_by_suggestion_id profile.id
  503 + suggestion.disable if suggestion
  504 + end
  505 +
501 506 protected
502 507  
503 508 def followed_by?(profile)
... ...
app/models/profile_suggestion.rb
... ... @@ -2,7 +2,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base
2 2 belongs_to :person
3 3 belongs_to :suggestion, :class_name => 'Profile', :foreign_key => :suggestion_id
4 4  
5   - attr_accessible :person, :suggestion, :suggestion_type, :categories, :similarity, :enabled
  5 + attr_accessible :person, :suggestion, :suggestion_type, :categories, :enabled
6 6  
7 7 before_create do |profile_suggestion|
8 8 profile_suggestion.suggestion_type = self.suggestion.class.to_s
... ... @@ -18,11 +18,15 @@ class ProfileSuggestion &lt; ActiveRecord::Base
18 18 end
19 19  
20 20 validates_uniqueness_of :suggestion_id, :scope => [ :person_id ]
  21 + scope :of_person, :conditions => { :suggestion_type => 'Person' }
  22 + scope :of_community, :conditions => { :suggestion_type => 'Community' }
  23 + scope :enabled, :conditions => { :enabled => true }
21 24  
  25 + # {:category_type => ['category-icon', 'category-label']}
22 26 CATEGORIES = {
23   - :common_friends => _('Friends in common'),
24   - :common_communities => _('Communities in common'),
25   - :common_tags => _('Tags in common')
  27 + :common_friends => ['menu-people', _('Friends in common')],
  28 + :common_communities => ['menu-community',_('Communities in common')],
  29 + :common_tags => ['edit', _('Tags in common')]
26 30 }
27 31  
28 32 CATEGORIES.keys.each do |category|
... ... @@ -30,6 +34,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base
30 34 attr_accessible category.to_sym
31 35 end
32 36  
  37 + def category_icon(category)
  38 + 'icon-' + ProfileSuggestion::CATEGORIES[category][0]
  39 + end
  40 +
  41 + def category_label(category)
  42 + ProfileSuggestion::CATEGORIES[category][1]
  43 + end
  44 +
33 45 RULES = %w[
34 46 friends_of_friends
35 47 people_with_common_communities
... ...
app/views/friends/_profile_list.html.erb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<ul class="profile-list">
  2 + <% profiles.each do |profile| %>
  3 + <li>
  4 + <%= link_to_profile profile_image(profile) + '<br/>' + profile.short_name,
  5 + profile.identifier, :class => 'profile-link' %>
  6 + <div class="controll">
  7 + <%= button_without_text :remove, content_tag('span',_('remove')),
  8 + { :action => 'remove', :id => profile.id },
  9 + :title => _('remove') %>
  10 + <%= button_without_text 'menu-mail', content_tag('span',_('contact')),
  11 + profile.url.merge(:controller => 'contact', :action => 'new', :profile => profile.identifier),
  12 + :title => _('contact') %>
  13 + </div><!-- end class="controll" -->
  14 + </li>
  15 + <% end %>
  16 +</ul>
... ...
app/views/friends/index.html.erb
... ... @@ -20,22 +20,23 @@
20 20 <% end %>
21 21 <% end %>
22 22  
23   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @friends, :collection => :friends } %>
24   - <div id='pagination-friends'>
25   - <%= pagination_links @friends, :param_name => 'npage' %>
26   - </div>
  23 + <%= render :partial => 'profile_list', :locals => { :profiles => @friends } %>
27 24  
  25 + <br style="clear:both" />
  26 + <%= pagination_links @friends, :param_name => 'npage' %>
28 27 <% end %>
29 28  
30 29 <% unless @suggestions.empty? %>
31 30 <br style="clear:both" />
32   - <h2><%= _("Friends suggestions") %></h2>
  31 + <div class="profiles-suggestions">
  32 + <h2><%= _("Friends suggestions") %></h2>
33 33  
34   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @suggestions, :collection => :friends_suggestions } %>
  34 + <%= render :partial => 'shared/profile_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions } %>
35 35  
36   - <% button_bar do %>
37   - <%= link_to _('See more suggestions...'), :action => 'suggest' %>
38   - <% end %>
  36 + <% button_bar do %>
  37 + <%= link_to _('See more suggestions...'), :action => 'suggest' %>
  38 + <% end %>
  39 + </div>
39 40 <% end %>
40 41  
41 42 </div><!-- end id="manage_friends" -->
... ...
app/views/friends/suggest.html.erb
... ... @@ -13,9 +13,7 @@
13 13 </em>
14 14 </p>
15 15 <% else %>
16   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @suggestions, :collection => :friends_suggestions } %>
17   -
18   - <%= pagination_links @suggestions, :param_name => 'npage' %>
  16 + <%= render :partial => 'shared/profile_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions } %>
19 17 <% end %>
20 18 <br style="clear:both" />
21 19 </div>
... ...
app/views/memberships/suggest.html.erb
... ... @@ -13,9 +13,7 @@
13 13 </em>
14 14 </p>
15 15 <% else %>
16   - <%= render :partial => 'shared/profile_list', :locals => { :profiles => @suggestions, :collection => :communities_suggestions } %>
  16 + <%= render :partial => 'shared/profile_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions } %>
17 17 <% end %>
18   -
19   - <%= pagination_links @suggestions, :param_name => 'npage' %>
20 18 <br style="clear:both" />
21 19 </div>
... ...
app/views/shared/_profile_list.html.erb
1 1 <ul class="profile-list">
2   - <% profiles.each do |profile| %>
  2 + <% suggestions.each do |s| %>
3 3 <li>
4   - <%= link_to_profile profile_image(profile) + '<br/>' + profile.short_name,
5   - profile.identifier, :class => 'profile-link' %>
6   - <div class="controll">
7   - <% if collection == :friends %>
8   - <%= button_without_text :remove, content_tag('span',_('remove')),
9   - { :action => 'remove', :id => profile.id },
10   - :title => _('remove') %>
11   - <%= button_without_text 'menu-mail', content_tag('span',_('contact')),
12   - profile.url.merge(:controller => 'contact', :action => 'new', :profile => profile.identifier),
13   - :title => _('contact') %>
14   - <% elsif collection == :friends_suggestions %>
15   - <%= button_without_text :add, content_tag('span',_('add')),
16   - profile.add_url,
17   - :class => 'add-friend',
18   - :title => _('Add friend') %>
19   - <%= button_without_text :remove, content_tag('span',_('remove')),
20   - { :action => 'remove_suggestion', :id => profile.identifier },
21   - :title => _('Remove suggestion'),
22   - :method => 'post',
23   - :confirm => _('Are you sure you want to remove this suggestion?') %>
24   - <% elsif collection == :communities_suggestions %>
25   - <%= button_without_text :add, content_tag('span',_('join')),
26   - profile.join_url,
27   - :class => 'join-community',
28   - :title => _("Join %s") % profile.name %>
  4 + <%= link_to_profile profile_image(s.suggestion, :minor) + '<br/>' + s.suggestion.short_name,
  5 + s.suggestion.identifier, :class => 'profile-link' %>
  6 + <%= button_without_text :help, content_tag('span',_('info about suggestion')),
  7 + { :action => '#' },
  8 + :class => 'explain-suggestion',
  9 + :title => _('Why this suggestion?') %>
  10 + <div class='extra_info' style='display:none'>
  11 + <%= profile_suggestion_categories(s) %>
  12 + </div>
  13 + <div class="controll">
  14 + <% if collection == :friends_suggestions %>
  15 + <%= button_without_text :add, content_tag('span',_('add')),
  16 + s.suggestion.add_url,
  17 + :class => 'add-friend',
  18 + :title => _('Add friend') %>
29 19 <%= button_without_text :remove, content_tag('span',_('remove')),
30   - { :action => 'remove_suggestion', :id => profile.identifier },
  20 + { :action => 'remove_suggestion', :id => s.suggestion.identifier },
31 21 :title => _('Remove suggestion'),
32 22 :method => 'post',
33 23 :confirm => _('Are you sure you want to remove this suggestion?') %>
34   - <% end %>
35   - </div><!-- end class="controll" -->
  24 + <% elsif collection == :communities_suggestions %>
  25 + <%= button_without_text :add, content_tag('span',_('join')),
  26 + s.suggestion.join_url,
  27 + :class => 'join-community',
  28 + :title => _("Join %s") % s.suggestion.name %>
  29 + <%= button_without_text :remove, content_tag('span',_('remove')),
  30 + { :action => 'remove_suggestion', :id => s.suggestion.identifier },
  31 + :title => _('Remove suggestion'),
  32 + :method => 'post',
  33 + :confirm => _('Are you sure you want to remove this suggestion?') %>
  34 + <% end %>
  35 + </div><!-- end class="controll" -->
36 36 </li>
37 37 <% end %>
38 38 </ul>
... ...
app/views/user_mailer/profiles_suggestions_email.html.erb
1 1 <%= _('Hi, %{recipient}!') % { :recipient => @recipient } %>
2 2  
3   -<p><%= _('We want to give you some suggestions to grow up your network. Check it out!') %></p>
  3 +<p><%= _('We want to give you some suggestions to grow up your network.') %>
  4 +<p><%= _('Check it out!') %></p>
4 5  
5 6 <% unless @people_suggestions.empty? %>
6 7 <p><%= _('Friends suggestions:') %></p>
... ...
public/javascripts/application.js
... ... @@ -1053,6 +1053,14 @@ function showHideTermsOfUse() {
1053 1053 }
1054 1054 }
1055 1055  
  1056 +jQuery('.profiles-suggestions .explain-suggestion').live('click', function() {
  1057 + var clicked = jQuery(this);
  1058 + jQuery('.profiles-suggestions .extra_info').hide();
  1059 + clicked.toggleClass('active');
  1060 + clicked.next('.extra_info').toggle();
  1061 + return false;
  1062 +});
  1063 +
1056 1064 jQuery(document).ready(function(){
1057 1065 showHideTermsOfUse();
1058 1066  
... ...
public/stylesheets/application.css
... ... @@ -2131,7 +2131,8 @@ a.button.disabled, input.disabled {
2131 2131 #content .common-profile-list-block .sex-male span, #content .common-profile-list-block .sex-female span, #content .common-profile-list-block .sex-undef span {
2132 2132 display: none;
2133 2133 }
2134   -.common-profile-list-block .extra_info {
  2134 +.common-profile-list-block .extra_info,
  2135 +.profile-list .extra_info {
2135 2136 font-size: 9px;
2136 2137 opacity: 0.5;
2137 2138 filter: alpha(opacity=50);
... ... @@ -3955,16 +3956,24 @@ h1#agenda-title {
3955 3956 .controller-friends .profile-list li,
3956 3957 .profiles-suggestions .profile-list li {
3957 3958 float: left;
3958   - width: 90px;
  3959 + margin: 5px;
3959 3960 height: 90px;
3960   - max-width: 80px;
3961 3961 max-height: 80px;
3962   - margin: 5px;
3963 3962 padding: 5px;
3964 3963 border: 2px solid transparent;
3965 3964 list-style: none;
3966 3965 position: relative;
3967 3966 }
  3967 +.controller-favorite_enterprises .profile-list li,
  3968 +.controller-friends .profile-list li {
  3969 + width: 90px;
  3970 + max-width: 80px;
  3971 +}
  3972 +.profiles-suggestions .profile-list li {
  3973 + width: 76px;
  3974 + max-width: 76px;
  3975 +}
  3976 +
3968 3977 .controller-favorite_enterprises .profile-list li:hover,
3969 3978 .controller-friends .profile-list li:hover,
3970 3979 .profiles-suggestions .profile-list li:hover {
... ... @@ -4000,12 +4009,22 @@ h1#agenda-title {
4000 4009 .profiles-suggestions .profile-list {
4001 4010 position: relative;
4002 4011 }
  4012 +.profiles-suggestions .profile-list .explain-suggestion {
  4013 + position: absolute;
  4014 + top: 7px;
  4015 + left: -5px;
  4016 + z-index: 10;
  4017 +}
  4018 +#content .profiles-suggestions .profile-list .explain-suggestion.active {
  4019 + border-bottom-color: transparent;
  4020 +}
  4021 +
4003 4022 .controller-favorite_enterprises .profile-list .controll,
4004 4023 .controller-friends .profile-list .controll,
4005 4024 .profiles-suggestions .profile-list .controll {
4006 4025 position: absolute;
4007 4026 top: 7px;
4008   - right: -10px;
  4027 + right: -5px;
4009 4028 }
4010 4029 .controller-favorite_enterprises .profile-list .controll a,
4011 4030 .controller-friends .profile-list .controll a,
... ... @@ -4024,6 +4043,31 @@ h1#agenda-title {
4024 4043 clear: both;
4025 4044 padding-top: 20px;
4026 4045 }
  4046 +
  4047 +.profiles-suggestions .profile-list .extra_info {
  4048 + background: url("/images/down-arrow.png") no-repeat scroll center top #eee;
  4049 + border: 1px solid #ccc;
  4050 + left: -66px;
  4051 + min-width: 135px;
  4052 + padding: 5px;
  4053 + position: absolute;
  4054 + top: 29px;
  4055 + opacity: 0.9;
  4056 + z-index: 5;
  4057 +}
  4058 +
  4059 +.profiles-suggestions .profile-list .extra_info p {
  4060 + margin: 0px;
  4061 +}
  4062 +
  4063 +.profiles-suggestions .profile-list .extra_info span {
  4064 + background-position: 4px 50%;
  4065 + background-repeat: no-repeat;
  4066 + display: block;
  4067 + line-height: 20px;
  4068 + padding: 0 0 0 25px;
  4069 +}
  4070 +
4027 4071 /* ==> public/stylesheets/controller_friends.css <== */
4028 4072  
4029 4073 .controller-friends #remove_friend .friend_picture,
... ...
test/unit/person_test.rb
... ... @@ -1544,6 +1544,28 @@ class PersonTest &lt; ActiveSupport::TestCase
1544 1544 assert_equal [suggested_community], person.suggested_communities
1545 1545 end
1546 1546  
  1547 + should 'disable friend suggestion' do
  1548 + person = create_user('person').person
  1549 + suggested_person = fast_create(Person)
  1550 +
  1551 + suggestion = ProfileSuggestion.create(:person => person, :suggestion => suggested_person)
  1552 +
  1553 + assert_difference 'person.suggested_people.count', -1 do
  1554 + person.remove_suggestion(suggested_person)
  1555 + end
  1556 + end
  1557 +
  1558 + should 'disable community suggestion' do
  1559 + person = create_user('person').person
  1560 + suggested_community = fast_create(Community)
  1561 +
  1562 + suggestion = ProfileSuggestion.create(:person => person, :suggestion => suggested_community)
  1563 +
  1564 + assert_difference 'person.suggested_communities.count', -1 do
  1565 + person.remove_suggestion(suggested_community)
  1566 + end
  1567 + end
  1568 +
1547 1569 should 'return url to people suggestions for a person' do
1548 1570 environment = create_environment('mycolivre.net')
1549 1571 profile = build(Person, :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
... ...