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 554 trigger_class = 'enterprise-trigger'
555 555 end
556 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 568 links = links_for_balloon(profile)
559 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 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 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 576 profile.url,
566 577 :class => 'profile_link url',
567 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 720 class NoosferoFormBuilder < ActionView::Helpers::FormBuilder
710 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 724 # try to guess an id if none given
714 725 if field_id.nil?
715 726 field_html =~ /id=['"]([^'"]*)['"]/
... ...
app/models/profile.rb
... ... @@ -738,13 +738,13 @@ private :generate_url, :url_options
738 738 end
739 739  
740 740 # Adds a person as member of this Profile.
741   - def add_member(person)
  741 + def add_member(person, attributes={})
742 742 if self.has_members?
743 743 if self.closed? && members.count > 0
744 744 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
745 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 748 end
749 749 person.tasks.pending.of("InviteMember").select { |t| t.data[:community_id] == self.id }.each { |invite| invite.cancel }
750 750 remove_from_suggestion_list person
... ...
app/views/profile/_profile_members_list.html.erb
... ... @@ -9,7 +9,8 @@
9 9 </div>
10 10 <ul class="profile-list-<%= role %>" >
11 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 14 <% end %>
14 15 </ul>
15 16  
... ...
app/views/profile/members.html.erb
... ... @@ -19,7 +19,6 @@
19 19 :id => "members-tab",
20 20 :content => div_members
21 21 } %>
22   -
23 22 <% div_admins = content_tag :div, :class => "profile-admins" do
24 23 render :partial => 'profile_members_list',
25 24 :locals => {
... ...
db/migrate/20160202142247_add_timestamps_to_role_assignments.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddTimestampsToRoleAssignments < ActiveRecord::Migration
  2 + def change
  3 + add_timestamps :role_assignments
  4 + end
  5 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 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 16 # These are extensions that must be enabled in order to support this database
17 17 enable_extension "plpgsql"
... ... @@ -639,12 +639,14 @@ ActiveRecord::Schema.define(version: 20150921140802) do
639 639 end
640 640  
641 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 650 end
649 651  
650 652 create_table "roles", force: :cascade do |t|
... ...
public/stylesheets/profile-list.scss
... ... @@ -207,3 +207,23 @@
207 207 height: auto;
208 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 @@
  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 1043 assert_equal c.top_url, top_url
1044 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 1071 protected
1047 1072 include NoosferoTestHelper
1048 1073  
... ...
test/unit/person_test.rb
... ... @@ -1925,5 +1925,13 @@ class PersonTest &lt; ActiveSupport::TestCase
1925 1925 assert_equal 2, Person.with_role(Profile::Roles.moderator(c1.environment.id).id).count
1926 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 1937 end
... ...
vendor/plugins/access_control/lib/acts_as_accessible.rb
... ... @@ -19,9 +19,9 @@ module ActsAsAccessible
19 19 nil
20 20 end
21 21  
22   - def affiliate(accessor, roles)
  22 + def affiliate(accessor, roles, attributes = {})
23 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 25 end
26 26  
27 27 def disaffiliate(accessor, roles)
... ...
vendor/plugins/access_control/lib/acts_as_accessor.rb
... ... @@ -21,9 +21,9 @@ module ActsAsAccessor
21 21 (actual_roles - roles).each {|r| remove_role(r, resource)}
22 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 27 ra = RoleAssignment.new(attributes)
28 28 role_assignments << ra
29 29 resource.role_assignments << ra
... ... @@ -44,6 +44,19 @@ module ActsAsAccessor
44 44 RoleAssignment.where(role_attributes nil, res)
45 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 60 protected
48 61 def role_attributes(role, resource)
49 62 attributes = {:accessor_id => self.id, :accessor_type => self.class.base_class.name}
... ...
vendor/plugins/access_control/lib/role_assignment.rb
1 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 5 belongs_to :role
6 6 belongs_to :accessor, :polymorphic => true
... ...