Commit 7949d4e822a87f1fef6fd229ba5bdf7b5233238c

Authored by Marcos Pereira
1 parent e9dec90f

Adds required email moderation option

- Confirmation modal when joining community
- Moderation option in community control panel

Signed-off-by: Alexandre Barbosa <alexandreab@live.com>
Signed-off-by: Alvaro Fernando <alvarofernandoms@gmail.com>
Signed-off-by: Gabriel Silva <gabriel93.silva@gmail.com>
Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>
app/controllers/public/profile_controller.rb
@@ -86,8 +86,17 @@ class ProfileController &lt; PublicController @@ -86,8 +86,17 @@ class ProfileController &lt; PublicController
86 @articles = profile.top_level_articles.includes([:profile, :parent]) 86 @articles = profile.top_level_articles.includes([:profile, :parent])
87 end 87 end
88 88
  89 + def join_modal
  90 + profile.add_member(user)
  91 + session[:notice] = _('%s administrator still needs to accept you as member.') % profile.name
  92 + redirect_to :action => :index
  93 + end
  94 +
89 def join 95 def join
90 if !user.memberships.include?(profile) 96 if !user.memberships.include?(profile)
  97 + return if profile.community? && profile.requires_email &&
  98 + current_person && !current_person.public_fields.include?("email")
  99 +
91 profile.add_member(user) 100 profile.add_member(user)
92 if !profile.members.include?(user) 101 if !profile.members.include?(user)
93 render :text => {:message => _('%s administrator still needs to accept you as member.') % profile.name}.to_json 102 render :text => {:message => _('%s administrator still needs to accept you as member.') % profile.name}.to_json
app/helpers/application_helper.rb
@@ -54,6 +54,8 @@ module ApplicationHelper @@ -54,6 +54,8 @@ module ApplicationHelper
54 54
55 include TaskHelper 55 include TaskHelper
56 56
  57 + include MembershipsHelper
  58 +
57 def locale 59 def locale
58 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale 60 (@page && !@page.language.blank?) ? @page.language : FastGettext.locale
59 end 61 end
@@ -984,11 +986,11 @@ module ApplicationHelper @@ -984,11 +986,11 @@ module ApplicationHelper
984 986
985 def task_information(task) 987 def task_information(task)
986 values = {} 988 values = {}
  989 + values.merge!(task.information[:variables]) if task.information[:variables]
987 values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor 990 values.merge!({:requestor => link_to(task.requestor.name, task.requestor.url)}) if task.requestor
988 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject 991 values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject
989 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject 992 values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject
990 - values.merge!(task.information[:variables]) if task.information[:variables]  
991 - task.information[:message] % values 993 + (task.information[:message] % values).html_safe
992 end 994 end
993 995
994 def add_zoom_to_article_images 996 def add_zoom_to_article_images
app/helpers/memberships_helper.rb
1 module MembershipsHelper 1 module MembershipsHelper
  2 +
  3 + def join_community_button(logged)
  4 + url = logged ? profile.join_url : profile.join_not_logged_url
  5 +
  6 + if profile.requires_email? && current_person && !current_person.public_fields.include?("email")
  7 + modal_button :add, _('Join this community'), url, class: 'join-community'
  8 + else
  9 + button :add, _('Join this community'), url, class: 'join-community'
  10 + end
  11 + end
2 end 12 end
app/models/add_member.rb
@@ -29,16 +29,18 @@ class AddMember &lt; Task @@ -29,16 +29,18 @@ class AddMember &lt; Task
29 end 29 end
30 30
31 def information 31 def information
32 - requestor_email = " (#{requestor.email})" if requestor.may_display_field_to?("email")  
33 -  
34 - {:message => _("%{requestor}%{requestor_email} wants to be a member of '%{organization}'."),  
35 - variables: {requestor: requestor.name, requestor_email: requestor_email, organization: organization.name}} 32 + {:message => _("%{requestor} wants to be a member of '%{target}'."),
  33 + variables: {requestor: requestor.name, target: target.name}}
36 end 34 end
37 35
38 def accept_details 36 def accept_details
39 true 37 true
40 end 38 end
41 39
  40 + def footer
  41 + true
  42 + end
  43 +
42 def icon 44 def icon
43 {:type => :profile_image, :profile => requestor, :url => requestor.url} 45 {:type => :profile_image, :profile => requestor, :url => requestor.url}
44 end 46 end
app/models/community.rb
@@ -2,6 +2,7 @@ class Community &lt; Organization @@ -2,6 +2,7 @@ class Community &lt; Organization
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
4 attr_accessible :address_reference, :district, :tag_list, :language, :description 4 attr_accessible :address_reference, :district, :tag_list, :language, :description
  5 + attr_accessible :requires_email
5 after_destroy :check_invite_member_for_destroy 6 after_destroy :check_invite_member_for_destroy
6 7
7 def self.type_name 8 def self.type_name
@@ -12,6 +13,9 @@ class Community &lt; Organization @@ -12,6 +13,9 @@ class Community &lt; Organization
12 N_('Language') 13 N_('Language')
13 14
14 settings_items :language 15 settings_items :language
  16 + settings_items :requires_email, :type => :boolean
  17 +
  18 + alias_method :requires_email?, :requires_email
15 19
16 extend SetProfileRegionFromCityState::ClassMethods 20 extend SetProfileRegionFromCityState::ClassMethods
17 set_profile_region_from_city_state 21 set_profile_region_from_city_state
app/models/task.rb
@@ -190,6 +190,10 @@ class Task &lt; ApplicationRecord @@ -190,6 +190,10 @@ class Task &lt; ApplicationRecord
190 false 190 false
191 end 191 end
192 192
  193 + def footer
  194 + false
  195 + end
  196 +
193 def icon 197 def icon
194 {:type => :defined_image, :src => "/images/icons-app/user-minor.png", :name => requestor.name, :url => requestor.url} 198 {:type => :defined_image, :src => "/images/icons-app/user-minor.png", :name => requestor.name, :url => requestor.url}
195 end 199 end
app/views/blocks/profile_info_actions/_join_leave_community.html.erb
@@ -7,15 +7,12 @@ @@ -7,15 +7,12 @@
7 <%= button :delete, content_tag('span', _('Leave community')), profile.leave_url, 7 <%= button :delete, content_tag('span', _('Leave community')), profile.leave_url,
8 class: 'leave-community', 8 class: 'leave-community',
9 style: 'position: relative;' %> 9 style: 'position: relative;' %>
10 - <%= button :add, content_tag('span', _('Join this community')), profile.join_url,  
11 - class: 'join-community',  
12 - style: 'position: relative; display: none;' %>  
13 <% else %> 10 <% else %>
14 - <%= button :add, _('Join this community'), profile.join_url, class: 'join-community' %> 11 + <%= join_community_button(true) %>
15 <% end %> 12 <% end %>
16 <% end %> 13 <% end %>
17 <% else %> 14 <% else %>
18 - <%= button :add, _('Join this community'), profile.join_not_logged_url %> 15 + <%= join_community_button(false) %>
19 <% end %> 16 <% end %>
20 </div> 17 </div>
21 18
app/views/profile/join.html.erb
1 -<h1><%= _('Joining %s') % profile.name %></h1> 1 +<div class="join-community-confirmation">
2 2
3 -<p>  
4 -<%= _('Are you sure you want to join %s?') % profile.name %>  
5 -</p> 3 + <h1><%= _('To join %s, you must:') % profile.name %></h1>
6 4
7 -<%= form_tag do %>  
8 - <%= hidden_field_tag('back_to', @back_to) %>  
9 - <%= hidden_field_tag(:confirmation, 1) %>  
10 - <%= submit_button(:ok, _("Yes, I want to join.") % profile.name) %>  
11 - <% if logged_in? && request.xhr? %>  
12 - <%= modal_close_button _("No, I don't want") %>  
13 - <% else %>  
14 - <%= button(:cancel, _("No, I don't want."), profile.url) %> 5 + <p>
  6 + <%= _("Authorize the visibility of your email address to the community administrator.") %>
  7 + </p>
  8 +
  9 + <%= form_tag url_for({:action => :join_modal, :controller => :profile}) do %>
  10 + <%= hidden_field_tag('back_to', @back_to) %>
  11 + <%= submit_button(:ok, _("Authorize")) %>
  12 + <%= modal_close_button _("Cancel") %>
15 <% end %> 13 <% end %>
16 -<% end %> 14 +
  15 +</div>
  16 +
app/views/profile_editor/_moderation.html.erb
@@ -9,7 +9,6 @@ @@ -9,7 +9,6 @@
9 <%= _('Send administrator Email for every task') %> 9 <%= _('Send administrator Email for every task') %>
10 </div> 10 </div>
11 </div> 11 </div>
12 -  
13 <div style='margin-bottom: 1em'> 12 <div style='margin-bottom: 1em'>
14 <h4><%= _('Invitation moderation:')%></h4> 13 <h4><%= _('Invitation moderation:')%></h4>
15 </div> 14 </div>
@@ -36,6 +35,12 @@ @@ -36,6 +35,12 @@
36 <div style='margin-left: 30px'> 35 <div style='margin-left: 30px'>
37 <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).').html_safe %> 36 <%= _('<strong>Before</strong> joining this group (a moderator has to accept the member in pending request before member can access the intranet and/or the website).').html_safe %>
38 </div> 37 </div>
  38 + <div id = "requires_email_option" style="margin-left: 30px; margin-top: 10px; margin-bottom: 15px;<%=" display: none;" unless profile.closed? %>">
  39 + <%= check_box(:profile_data, :requires_email, :style => 'float: left') %>
  40 + <div style='margin-left: 30px'>
  41 + <%= _('New members must allow email visibility to the profile admin') %>
  42 + </div>
  43 + </div>
39 </div> 44 </div>
40 <div> 45 <div>
41 <%= radio_button 'profile_data', 'closed', 'false', :style => 'float: left' %> 46 <%= radio_button 'profile_data', 'closed', 'false', :style => 'float: left' %>
app/views/tasks/_add_member_footer.html.erb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +<% if (task.organization.requires_email || task.requestor.may_display_field_to?("email")) %>
  2 + <div>
  3 + Email:
  4 + <span id="task_email"> <%=task.requestor.email %> </span>
  5 + </div>
  6 +<% end %>
  7 +
app/views/tasks/_task.html.erb
@@ -70,4 +70,10 @@ @@ -70,4 +70,10 @@
70 <% end %> 70 <% end %>
71 <% end %> 71 <% end %>
72 72
  73 + <% if task.footer %>
  74 + <div id="task-footer-<%=task.id%>">
  75 + <%= render :partial => partial_for_class(task.class, nil, :footer), :locals => {:task => task} %>
  76 + </div>
  77 + <% end %>
  78 +
73 </div><!-- class="task_box" --> 79 </div><!-- class="task_box" -->
public/designs/themes/base/style.scss
@@ -1555,3 +1555,21 @@ table#recaptcha_table tr:hover td { @@ -1555,3 +1555,21 @@ table#recaptcha_table tr:hover td {
1555 clear: both; 1555 clear: both;
1556 } 1556 }
1557 1557
  1558 +
  1559 +/*************************** join community confirmation ********************************/
  1560 +
  1561 +.join-community-confirmation h1 {
  1562 + font-variant: small-caps;
  1563 + font-size: 20px;
  1564 + color: #555753;
  1565 + text-align: left;
  1566 +}
  1567 +
  1568 +.join-community-confirmation {
  1569 + padding: 5px 20px 0px 20px;
  1570 +}
  1571 +
  1572 +.join-community-confirmation input.button.with-text {
  1573 + padding-right: 4px;
  1574 +}
  1575 +
public/javascripts/add-and-join.js
@@ -18,9 +18,11 @@ jQuery(function($) { @@ -18,9 +18,11 @@ jQuery(function($) {
18 }) 18 })
19 19
20 $(".join-community").live('click', function(){ 20 $(".join-community").live('click', function(){
  21 + $('#cboxClose').remove();
21 clicked = $(this); 22 clicked = $(this);
22 url = clicked.attr("href"); 23 url = clicked.attr("href");
23 - loading_for_button(this); 24 + if (!clicked.hasClass('modal-toggle'))
  25 + loading_for_button(this);
24 $.post(url, function(data){ 26 $.post(url, function(data){
25 clicked.fadeOut(function(){ 27 clicked.fadeOut(function(){
26 clicked.css("display","none"); 28 clicked.css("display","none");
public/javascripts/profile_editor.js
@@ -23,4 +23,14 @@ @@ -23,4 +23,14 @@
23 }); 23 });
24 24
25 }); 25 });
  26 +
  27 + $("#profile_data_closed_false").click(function(){
  28 + $("#requires_email_option").prop("checked",false);
  29 + $("#requires_email_option").hide();
  30 + });
  31 +
  32 + $("#profile_data_closed_true").click(function(){
  33 + $("#requires_email_option").show();
  34 + });
  35 +
26 })(jQuery); 36 })(jQuery);
test/functional/profile_controller_test.rb
@@ -3,6 +3,8 @@ require &#39;profile_controller&#39; @@ -3,6 +3,8 @@ require &#39;profile_controller&#39;
3 3
4 class ProfileControllerTest < ActionController::TestCase 4 class ProfileControllerTest < ActionController::TestCase
5 5
  6 + include MembershipsHelper
  7 +
6 self.default_params = {profile: 'testuser'} 8 self.default_params = {profile: 'testuser'}
7 def setup 9 def setup
8 @profile = create_user('testuser').person 10 @profile = create_user('testuser').person
@@ -384,6 +386,61 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -384,6 +386,61 @@ class ProfileControllerTest &lt; ActionController::TestCase
384 assert_redirected_to :controller => 'account', :action => 'login' 386 assert_redirected_to :controller => 'account', :action => 'login'
385 end 387 end
386 388
  389 + should 'show regular join button for person with public email' do
  390 + community = Community.create!(:name => 'my test community', :closed => true, :requires_email => true)
  391 + Person.any_instance.stubs(:public_fields).returns(["email"])
  392 + login_as(@profile.identifier)
  393 +
  394 + get :index, :profile => community.identifier
  395 + assert_no_tag :tag => 'a', :attributes => { :class => /modal-toggle join-community/ }
  396 + end
  397 +
  398 + should 'show join modal for person with private email' do
  399 + community = Community.create!(:name => 'my test community', :closed => true, :requires_email => true)
  400 + Person.any_instance.stubs(:public_fields).returns([])
  401 + login_as(@profile.identifier)
  402 +
  403 + get :index, :profile => community.identifier
  404 + assert_tag :tag => 'a', :attributes => { :class => /modal-toggle join-community/ }
  405 + end
  406 +
  407 + should 'show regular join button for community without email visibility requirement' do
  408 + community = Community.create!(:name => 'my test community', :closed => true, :requires_email => false)
  409 + Person.any_instance.stubs(:public_fields).returns([])
  410 + login_as(@profile.identifier)
  411 +
  412 + get :index, :profile => community.identifier
  413 + assert_no_tag :tag => 'a', :attributes => { :class => /modal-toggle join-community/ }
  414 + end
  415 +
  416 + should 'show regular join button for community without email visibility requirement and person with public email' do
  417 + community = Community.create!(:name => 'my test community', :closed => true, :requires_email => false)
  418 + Person.any_instance.stubs(:public_fields).returns(['email'])
  419 + login_as(@profile.identifier)
  420 +
  421 + get :index, :profile => community.identifier
  422 + assert_no_tag :tag => 'a', :attributes => { :class => /modal-toggle join-community/ }
  423 + end
  424 +
  425 + should 'render join modal for community with email visibility requirement and person with private email' do
  426 + community = Community.create!(:name => 'my test community', :closed => true, :requires_email => true)
  427 + login_as @profile.identifier
  428 + post :join, :profile => community.identifier
  429 + assert_template "join"
  430 + end
  431 +
  432 + should 'create add member task from join-community modal' do
  433 + community = Community.create!(:name => 'my test community', :closed => true, :requires_email => true)
  434 + admin = create_user('community-admin').person
  435 + community.add_admin(admin)
  436 +
  437 + login_as @profile.identifier
  438 + assert_difference 'AddMember.count' do
  439 + post :join_modal, :profile => community.identifier
  440 + end
  441 + assert_redirected_to :action => 'index'
  442 + end
  443 +
387 should 'actually leave profile' do 444 should 'actually leave profile' do
388 community = fast_create(Community) 445 community = fast_create(Community)
389 admin = fast_create(Person) 446 admin = fast_create(Person)