Commit 27f11bf70f49c69586dfd9c479d448642e7cecf1

Authored by Daniela Feitosa
2 parents 99422d53 13635dd8

Merge branch 'tasks_text_filter_with_autocomplete' into 'master'

Autocomplete tasks by name in administration area.

- Create a text field to autocomplete administration tasks.

Signed-off-by: Leandro Nunes <lenadronunes@gmail.com>
Signed-off-by: Michel Felipe <mfelipeof@gmail.com>

See merge request !831
app/controllers/my_profile/tasks_controller.rb
@@ -14,16 +14,15 @@ class TasksController &lt; MyProfileController @@ -14,16 +14,15 @@ class TasksController &lt; MyProfileController
14 @filter_text = params[:filter_text].presence 14 @filter_text = params[:filter_text].presence
15 @filter_responsible = params[:filter_responsible] 15 @filter_responsible = params[:filter_responsible]
16 @task_types = Task.pending_types_for(profile) 16 @task_types = Task.pending_types_for(profile)
17 -  
18 - @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc') 17 + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
19 @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present? 18 @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present?
20 @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) 19 @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page])
21 -  
22 @failed = params ? params[:failed] : {} 20 @failed = params ? params[:failed] : {}
23 21
24 @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization? 22 @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization?
25 23
26 @view_only = !current_person.has_permission?(:perform_task, profile) 24 @view_only = !current_person.has_permission?(:perform_task, profile)
  25 +
27 end 26 end
28 27
29 def processed 28 def processed
@@ -95,4 +94,12 @@ class TasksController &lt; MyProfileController @@ -95,4 +94,12 @@ class TasksController &lt; MyProfileController
95 @ticket = Ticket.where('(requestor_id = ? or target_id = ?) and id = ?', profile.id, profile.id, params[:id]).first 94 @ticket = Ticket.where('(requestor_id = ? or target_id = ?) and id = ?', profile.id, profile.id, params[:id]).first
96 end 95 end
97 96
  97 + def search_tasks
  98 + filter_type = params[:filter_type].presence
  99 + filter_text = params[:filter_text].presence
  100 + result = Task.pending_all(profile,filter_type, filter_text)
  101 +
  102 + render :json => result.map { |task| {:label => task.data[:name], :value => task.data[:name]} }
  103 + end
  104 +
98 end 105 end
app/models/task.rb
@@ -324,6 +324,7 @@ class Task &lt; ActiveRecord::Base @@ -324,6 +324,7 @@ class Task &lt; ActiveRecord::Base
324 where [environment_condition, profile_condition].compact.join(' OR ') 324 where [environment_condition, profile_condition].compact.join(' OR ')
325 } 325 }
326 326
  327 +
327 def self.pending_types_for(profile) 328 def self.pending_types_for(profile)
328 Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] } 329 Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] }
329 end 330 end
app/views/tasks/index.html.erb
@@ -21,25 +21,20 @@ @@ -21,25 +21,20 @@
21 </div> 21 </div>
22 <% end %> 22 <% end %>
23 23
24 -<%= form_tag '#', :method => 'get' do %>  
25 - <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>  
26 - <p>  
27 - <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>  
28 - </p>  
29 - <p>  
30 - <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %>  
31 - </p>  
32 - <% if profile.organization? %>  
33 - <p>  
34 - <%= labelled_select(_('Assigned to')+': ', :filter_responsible, :id, :name, @filter_responsible, [OpenStruct.new(:name => _('All'), :id => nil), OpenStruct.new(:name => _('Unassigned'), :id => -1)] + @responsible_candidates, :class => 'filter_responsible') %>  
35 - </p> 24 +<%= form_tag '#', :method => 'post' do %>
  25 +
  26 + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>
  27 + <p>
  28 + <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>
  29 + </p>
  30 + <p>
  31 + <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text-autocomplete',:value => @filter_text}) %>
  32 + </p>
  33 + <p>
  34 + <%= submit_button(:search, _('Search')) %>
  35 + </p>
36 <% end %> 36 <% end %>
37 - <p>  
38 - <%= submit_button(:search, _('Search')) %>  
39 - </p>  
40 - <% end %>  
41 <% end %> 37 <% end %>
42 -  
43 <% if @tasks.empty? %> 38 <% if @tasks.empty? %>
44 <p> 39 <p>
45 <em><%= _('No pending tasks for %s') % profile.name %></em> 40 <em><%= _('No pending tasks for %s') % profile.name %></em>
@@ -59,18 +54,18 @@ @@ -59,18 +54,18 @@
59 <p> 54 <p>
60 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %> 55 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
61 </p> 56 </p>
62 - <% end %> 57 + <% end %>
63 58
64 <div class="task_boxes"> 59 <div class="task_boxes">
65 <%= render :partial => 'task', :collection => @tasks %> 60 <%= render :partial => 'task', :collection => @tasks %>
66 </div> 61 </div>
67 62
68 <% unless @view_only %> 63 <% unless @view_only %>
69 - <p>  
70 - <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>  
71 - </p> 64 + <p>
  65 + <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
  66 + </p>
72 <% end %> 67 <% end %>
73 - </ul> 68 + </ul>
74 69
75 <%= pagination_links(@tasks)%> 70 <%= pagination_links(@tasks)%>
76 71
public/javascripts/tasks.js
@@ -58,6 +58,22 @@ @@ -58,6 +58,22 @@
58 $('.task_title').css('margin-right', $('.task_decisions').width()+'px'); 58 $('.task_title').css('margin-right', $('.task_decisions').width()+'px');
59 $('.task_title').css('margin-left', $('.task_arrow').width()+'px'); 59 $('.task_title').css('margin-left', $('.task_arrow').width()+'px');
60 60
  61 + //Autocomplete tasks by type
  62 + $('#filter-text-autocomplete').autocomplete({
  63 + source:function(request,response){
  64 + $.ajax({
  65 + url:document.location.pathname+'/search_tasks',
  66 + dataType:'json',
  67 + data:{
  68 + filter_text:request.term,
  69 + filter_type:jQuery('#filter-type').val()
  70 + },
  71 + success:response
  72 + })
  73 + },
  74 + minLength:2
  75 + });
  76 +
61 })(jQuery) 77 })(jQuery)
62 78
63 function change_task_responsible(el) { 79 function change_task_responsible(el) {
test/functional/tasks_controller_test.rb
@@ -4,6 +4,7 @@ require &#39;tasks_controller&#39; @@ -4,6 +4,7 @@ require &#39;tasks_controller&#39;
4 class TasksControllerTest < ActionController::TestCase 4 class TasksControllerTest < ActionController::TestCase
5 5
6 self.default_params = {profile: 'testuser'} 6 self.default_params = {profile: 'testuser'}
  7 +
7 def setup 8 def setup
8 @controller = TasksController.new 9 @controller = TasksController.new
9 @request = ActionController::TestRequest.new 10 @request = ActionController::TestRequest.new
@@ -27,6 +28,37 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -27,6 +28,37 @@ class TasksControllerTest &lt; ActionController::TestCase
27 assert assigns(:tasks) 28 assert assigns(:tasks)
28 end 29 end
29 30
  31 + should 'get filtered tasks to autocomplete text field' do
  32 +
  33 + #Create a admin user and a simple user
  34 + profile_admin = create_user('admin_tester').person
  35 + Environment.default.add_admin(profile_admin)
  36 + user = fast_create(Person,:name => 'FakeUser')
  37 +
  38 + #Create a task of type 'ModerateUserRegistration'
  39 + task_data = {
  40 + :target => Environment.default,
  41 + :spam => false,
  42 + :data => {:user_id => user.id,:name => user.name}
  43 + }
  44 + ModerateUserRegistration.create!(task_data)
  45 +
  46 + #Use admin user to your profile with a pending task above
  47 + @controller.stubs(:profile).returns(profile_admin)
  48 + login_as profile_admin.identifier
  49 +
  50 + #Perform a http request to 'search_task' action with params
  51 + post :search_tasks, :filter_type =>'ModerateUserRegistration', :filter_text => 'Fak'
  52 +
  53 + assert_response :success
  54 +
  55 + #Check if json response matches with a 'FakeUser'
  56 + json_response = ActiveSupport::JSON.decode(@response.body)
  57 + value = json_response[0]['value']
  58 +
  59 + assert_equal value, 'FakeUser'
  60 + end
  61 +
30 should 'list pending tasks without spam' do 62 should 'list pending tasks without spam' do
31 requestor = fast_create(Person) 63 requestor = fast_create(Person)
32 task_spam = Task.create!(:requestor => requestor, :target => profile, :spam => true) 64 task_spam = Task.create!(:requestor => requestor, :target => profile, :spam => true)
@@ -437,13 +469,13 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -437,13 +469,13 @@ class TasksControllerTest &lt; ActionController::TestCase
437 t2 = CleanHouse.create!(:requestor => requestor, :target => profile) 469 t2 = CleanHouse.create!(:requestor => requestor, :target => profile)
438 t3 = FeedDog.create!(:requestor => requestor, :target => profile) 470 t3 = FeedDog.create!(:requestor => requestor, :target => profile)
439 471
440 - get :index, :filter_type => t1.type, :filter_text => 'test' 472 + post :index, :filter_type => t1.type, :filter_text => 'test'
441 473
442 assert_includes assigns(:tasks), t1 474 assert_includes assigns(:tasks), t1
443 assert_not_includes assigns(:tasks), t2 475 assert_not_includes assigns(:tasks), t2
444 assert_not_includes assigns(:tasks), t3 476 assert_not_includes assigns(:tasks), t3
445 477
446 - get :index 478 + post :index
447 479
448 assert_includes assigns(:tasks), t1 480 assert_includes assigns(:tasks), t1
449 assert_includes assigns(:tasks), t2 481 assert_includes assigns(:tasks), t2