Commit 810b5519a12915d9753bb6e0cf72c694a49c91b3

Authored by Michel Felipe
Committed by Rodrigo Souto
1 parent 3ac7b587

Added new community member highlight.

* Mark new members with a label on top of image profile.

Signed-off-by: Lucas Kanashiro <kanashiro.duarte@gmail.com>
Signed-off-by: Rodrigo Siqueira <siqueira@kuniri.org>
app/helpers/application_helper.rb
@@ -554,14 +554,25 @@ module ApplicationHelper @@ -554,14 +554,25 @@ module ApplicationHelper
554 trigger_class = 'enterprise-trigger' 554 trigger_class = 'enterprise-trigger'
555 end 555 end
556 end 556 end
557 - extra_info = extra_info.nil? ? '' : content_tag( 'span', extra_info, :class => 'extra_info' ) 557 +
  558 + extra_info_tag = ''
  559 + img_class = 'profile-image'
  560 +
  561 + if extra_info.is_a? Hash
  562 + extra_info_tag = content_tag( 'span', extra_info[:value], :class => 'extra_info '+extra_info[:class])
  563 + img_class +=' '+extra_info[:class]
  564 + else
  565 + extra_info_tag = content_tag( 'span', extra_info, :class => 'extra_info' )
  566 + end
  567 +
558 links = links_for_balloon(profile) 568 links = links_for_balloon(profile)
559 content_tag('div', content_tag(tag, 569 content_tag('div', content_tag(tag,
560 - (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") + 570 + (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ?
  571 + popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") +
561 link_to( 572 link_to(
562 - content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) + 573 + content_tag( 'span', profile_image( profile, size ), :class => img_class ) +
563 content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) + 574 content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) +
564 - extra_info + profile_sex_icon( profile ), 575 + extra_info_tag + profile_sex_icon( profile ),
565 profile.url, 576 profile.url,
566 :class => 'profile_link url', 577 :class => 'profile_link url',
567 :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name, 578 :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name,
@@ -709,7 +720,7 @@ module ApplicationHelper @@ -709,7 +720,7 @@ module ApplicationHelper
709 class NoosferoFormBuilder < ActionView::Helpers::FormBuilder 720 class NoosferoFormBuilder < ActionView::Helpers::FormBuilder
710 extend ActionView::Helpers::TagHelper 721 extend ActionView::Helpers::TagHelper
711 722
712 - def self.output_field(text, field_html, field_id = nil, options = {}) 723 + def self.output_field(text, field_html, field_id = nil)
713 # try to guess an id if none given 724 # try to guess an id if none given
714 if field_id.nil? 725 if field_id.nil?
715 field_html =~ /id=['"]([^'"]*)['"]/ 726 field_html =~ /id=['"]([^'"]*)['"]/
app/models/profile.rb
@@ -738,13 +738,13 @@ private :generate_url, :url_options @@ -738,13 +738,13 @@ private :generate_url, :url_options
738 end 738 end
739 739
740 # Adds a person as member of this Profile. 740 # Adds a person as member of this Profile.
741 - def add_member(person) 741 + def add_member(person, attributes={})
742 if self.has_members? 742 if self.has_members?
743 if self.closed? && members.count > 0 743 if self.closed? && members.count > 0
744 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) 744 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
745 else 745 else
746 - self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0  
747 - self.affiliate(person, Profile::Roles.member(environment.id)) 746 + self.affiliate(person, Profile::Roles.admin(environment.id), attributes) if members.count == 0
  747 + self.affiliate(person, Profile::Roles.member(environment.id), attributes)
748 end 748 end
749 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel } 749 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel }
750 remove_from_suggestion_list person 750 remove_from_suggestion_list person
app/views/profile/_profile_members_list.html.erb
@@ -9,7 +9,8 @@ @@ -9,7 +9,8 @@
9 </div> 9 </div>
10 <ul class="profile-list-<%= role %>" > 10 <ul class="profile-list-<%= role %>" >
11 <% users.each do |u| %> 11 <% users.each do |u| %>
12 - <%= profile_image_link(u, :thumb) %> 12 + <% extra_info = u.member_since_date(profile) == Date.today ? {:value =>_('New'), :class => 'new-profile'}:'' %>
  13 + <%= profile_image_link(u, :thumb, 'li', extra_info) %>
13 <% end %> 14 <% end %>
14 </ul> 15 </ul>
15 16
app/views/profile/members.html.erb
@@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
19 :id => "members-tab", 19 :id => "members-tab",
20 :content => div_members 20 :content => div_members
21 } %> 21 } %>
22 -  
23 <% div_admins = content_tag :div, :class => "profile-admins" do 22 <% div_admins = content_tag :div, :class => "profile-admins" do
24 render :partial => 'profile_members_list', 23 render :partial => 'profile_members_list',
25 :locals => { 24 :locals => {
db/migrate/20160202142247_add_timestamps_to_role_assignments.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +class AddTimestampsToRoleAssignments < ActiveRecord::Migration
  2 + def change
  3 + add_timestamps :role_assignments
  4 + end
  5 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended that you check this file into your version control system. 12 # It's strongly recommended that you check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(version: 20150921140802) do 14 +ActiveRecord::Schema.define(version: 20160202142247) do
15 15
16 # These are extensions that must be enabled in order to support this database 16 # These are extensions that must be enabled in order to support this database
17 enable_extension "plpgsql" 17 enable_extension "plpgsql"
@@ -639,12 +639,14 @@ ActiveRecord::Schema.define(version: 20150921140802) do @@ -639,12 +639,14 @@ ActiveRecord::Schema.define(version: 20150921140802) do
639 end 639 end
640 640
641 create_table "role_assignments", force: :cascade do |t| 641 create_table "role_assignments", force: :cascade do |t|
642 - t.integer "accessor_id", null: false  
643 - t.string "accessor_type"  
644 - t.integer "resource_id"  
645 - t.string "resource_type"  
646 - t.integer "role_id", null: false  
647 - t.boolean "is_global" 642 + t.integer "accessor_id", null: false
  643 + t.string "accessor_type"
  644 + t.integer "resource_id"
  645 + t.string "resource_type"
  646 + t.integer "role_id", null: false
  647 + t.boolean "is_global"
  648 + t.datetime "created_at"
  649 + t.datetime "updated_at"
648 end 650 end
649 651
650 create_table "roles", force: :cascade do |t| 652 create_table "roles", force: :cascade do |t|
public/stylesheets/profile-list.scss
@@ -207,3 +207,23 @@ @@ -207,3 +207,23 @@
207 height: auto; 207 height: auto;
208 font-size: 12px; 208 font-size: 12px;
209 } 209 }
  210 +.action-profile-members .profile_link{
  211 + position: relative;
  212 +}
  213 +.action-profile-members .profile_link span.new-profile:last-child{
  214 + position: absolute;
  215 + top: 3px;
  216 + right: 2px;
  217 + text-transform: uppercase;
  218 + color: #FFF;
  219 + font-size: 9px;
  220 + background: #66CC33;
  221 + padding: 2px;
  222 + display: block;
  223 + width: 35px;
  224 + font-weight: 700;
  225 +}
  226 +.action-profile-members .profile_link .fn{
  227 + font-style: normal;
  228 + color: #000;
  229 +}
test/unit/access_control_test.rb 0 → 100644
@@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
  1 +
  2 +require_relative "../test_helper"
  3 +
  4 +class AccessControlTest < ActiveSupport::TestCase
  5 +
  6 + include ActsAsAccessor
  7 +
  8 + should 'raise exception if parameter is not a profile' do
  9 + assert_raises(TypeError) { member_relation_of(nil) }
  10 + end
  11 +
  12 + should 'Verify relation among member and community' do
  13 + person = fast_create(Person)
  14 + community = fast_create(Community)
  15 + assert_difference 'person.member_relation_of(community).count', 2 do
  16 + community.add_member(person)
  17 + end
  18 + end
  19 +
  20 + should 'Member does not belong to community' do
  21 + person = fast_create(Person)
  22 + community = fast_create(Community)
  23 + assert_nil person.member_since_date(community)
  24 + end
  25 +
  26 + should 'Verify if enter date of member in community is available' do
  27 + person = fast_create(Person)
  28 + community = fast_create(Community)
  29 + community.add_member(person)
  30 +
  31 + assert_instance_of Date, person.member_since_date(community)
  32 + end
  33 +
  34 +end
test/unit/application_helper_test.rb
@@ -1043,6 +1043,31 @@ class ApplicationHelperTest &lt; ActionView::TestCase @@ -1043,6 +1043,31 @@ class ApplicationHelperTest &lt; ActionView::TestCase
1043 assert_equal c.top_url, top_url 1043 assert_equal c.top_url, top_url
1044 end 1044 end
1045 1045
  1046 + should "Extra info with hash" do
  1047 + @plugins = mock
  1048 + @plugins.stubs(:dispatch_first).returns(false)
  1049 + env = Environment.default
  1050 + stubs(:environment).returns(env)
  1051 + stubs(:profile).returns(profile)
  1052 + profile = fast_create(Person, :environment_id => env.id)
  1053 + info = {:value =>_('New'), :class => 'new-profile'}
  1054 + html = profile_image_link(profile, size=:portrait, tag='li', extra_info = info)
  1055 + assert_tag_in_string html, :tag => 'span', :attributes => { :class => 'profile-image new-profile' }
  1056 + assert_tag_in_string html, :tag => 'span', :attributes => { :class => 'extra_info new-profile' }, :content => 'New'
  1057 + end
  1058 +
  1059 + should "Extra info without hash" do
  1060 + @plugins = mock
  1061 + @plugins.stubs(:dispatch_first).returns(false)
  1062 + env = Environment.default
  1063 + stubs(:environment).returns(env)
  1064 + stubs(:profile).returns(profile)
  1065 + profile = fast_create(Person, :environment_id => env.id)
  1066 + info = 'new'
  1067 + html = profile_image_link(profile, size=:portrait, tag='li', extra_info = info)
  1068 + assert_tag_in_string html, :tag => 'span', :attributes => { :class => 'extra_info' }, :content => 'new'
  1069 + end
  1070 +
1046 protected 1071 protected
1047 include NoosferoTestHelper 1072 include NoosferoTestHelper
1048 1073
test/unit/person_test.rb
@@ -1925,5 +1925,13 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1925,5 +1925,13 @@ class PersonTest &lt; ActiveSupport::TestCase
1925 assert_equal 2, Person.with_role(Profile::Roles.moderator(c1.environment.id).id).count 1925 assert_equal 2, Person.with_role(Profile::Roles.moderator(c1.environment.id).id).count
1926 end 1926 end
1927 1927
  1928 + should 'check if a person is added like a member of a community today' do
  1929 + person = create_user('person').person
  1930 + community = fast_create(Community)
1928 1931
  1932 + community.add_member person
  1933 +
  1934 + assert !person.member_relation_of(community).empty?, "Person '#{person.identifier}' is not a member of Community '#{community.identifier}'"
  1935 + assert person.member_since_date(community) == Date.today,"Person '#{person.identifier}' is not added like a member of Community '#{community.identifier}' today"
  1936 + end
1929 end 1937 end
vendor/plugins/access_control/lib/acts_as_accessible.rb
@@ -19,9 +19,9 @@ module ActsAsAccessible @@ -19,9 +19,9 @@ module ActsAsAccessible
19 nil 19 nil
20 end 20 end
21 21
22 - def affiliate(accessor, roles) 22 + def affiliate(accessor, roles, attributes = {})
23 roles = Array(roles) 23 roles = Array(roles)
24 - roles.map {|role| accessor.add_role(role, self)}.any? 24 + roles.map {|role| accessor.add_role(role, self, attributes)}.any?
25 end 25 end
26 26
27 def disaffiliate(accessor, roles) 27 def disaffiliate(accessor, roles)
vendor/plugins/access_control/lib/acts_as_accessor.rb
@@ -21,9 +21,9 @@ module ActsAsAccessor @@ -21,9 +21,9 @@ module ActsAsAccessor
21 (actual_roles - roles).each {|r| remove_role(r, resource)} 21 (actual_roles - roles).each {|r| remove_role(r, resource)}
22 end 22 end
23 23
24 - def add_role(role, resource)  
25 - attributes = role_attributes(role, resource)  
26 - if RoleAssignment.where(attributes).empty? 24 + def add_role(role, resource, attributes = {})
  25 + attributes = role_attributes(role, resource).merge attributes
  26 + if RoleAssignment.find(:all, :conditions => attributes).empty?
27 ra = RoleAssignment.new(attributes) 27 ra = RoleAssignment.new(attributes)
28 role_assignments << ra 28 role_assignments << ra
29 resource.role_assignments << ra 29 resource.role_assignments << ra
@@ -44,6 +44,19 @@ module ActsAsAccessor @@ -44,6 +44,19 @@ module ActsAsAccessor
44 RoleAssignment.where(role_attributes nil, res) 44 RoleAssignment.where(role_attributes nil, res)
45 end 45 end
46 46
  47 + def member_relation_of(profile)
  48 + raise TypeError, "Expected instance of 'Profile' class, but '#{profile.class.name}' was founded" unless profile.is_a? Profile
  49 +
  50 + role_assignments.where(resource_id: profile.id)
  51 + end
  52 +
  53 + def member_since_date(profile)
  54 + result = member_relation_of(profile).to_a
  55 + unless result.empty?
  56 + result.last.created_at ? result.last.created_at.to_date : Date.yesterday
  57 + end
  58 + end
  59 +
47 protected 60 protected
48 def role_attributes(role, resource) 61 def role_attributes(role, resource)
49 attributes = {:accessor_id => self.id, :accessor_type => self.class.base_class.name} 62 attributes = {:accessor_id => self.id, :accessor_type => self.class.base_class.name}
vendor/plugins/access_control/lib/role_assignment.rb
1 class RoleAssignment < ActiveRecord::Base 1 class RoleAssignment < ActiveRecord::Base
2 2
3 - attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type 3 + attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type, :created_at
4 4
5 belongs_to :role 5 belongs_to :role
6 belongs_to :accessor, :polymorphic => true 6 belongs_to :accessor, :polymorphic => true