Commit 13635dd88d20397838dae40b6c6adadc733cf55a

Authored by David Silva
1 parent 36dfeecb

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>
app/controllers/my_profile/tasks_controller.rb
... ... @@ -14,16 +14,15 @@ class TasksController &lt; MyProfileController
14 14 @filter_text = params[:filter_text].presence
15 15 @filter_responsible = params[:filter_responsible]
16 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 18 @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present?
20 19 @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page])
21   -
22 20 @failed = params ? params[:failed] : {}
23 21  
24 22 @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization?
25 23  
26 24 @view_only = !current_person.has_permission?(:perform_task, profile)
  25 +
27 26 end
28 27  
29 28 def processed
... ... @@ -95,4 +94,12 @@ class TasksController &lt; MyProfileController
95 94 @ticket = Ticket.where('(requestor_id = ? or target_id = ?) and id = ?', profile.id, profile.id, params[:id]).first
96 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 105 end
... ...
app/models/task.rb
... ... @@ -324,6 +324,7 @@ class Task &lt; ActiveRecord::Base
324 324 where [environment_condition, profile_condition].compact.join(' OR ')
325 325 }
326 326  
  327 +
327 328 def self.pending_types_for(profile)
328 329 Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] }
329 330 end
... ...
app/views/tasks/index.html.erb
... ... @@ -21,25 +21,20 @@
21 21 </div>
22 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 36 <% end %>
37   - <p>
38   - <%= submit_button(:search, _('Search')) %>
39   - </p>
40   - <% end %>
41 37 <% end %>
42   -
43 38 <% if @tasks.empty? %>
44 39 <p>
45 40 <em><%= _('No pending tasks for %s') % profile.name %></em>
... ... @@ -59,18 +54,18 @@
59 54 <p>
60 55 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
61 56 </p>
62   - <% end %>
  57 + <% end %>
63 58  
64 59 <div class="task_boxes">
65 60 <%= render :partial => 'task', :collection => @tasks %>
66 61 </div>
67 62  
68 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 67 <% end %>
73   - </ul>
  68 + </ul>
74 69  
75 70 <%= pagination_links(@tasks)%>
76 71  
... ...
public/javascripts/tasks.js
... ... @@ -58,6 +58,22 @@
58 58 $('.task_title').css('margin-right', $('.task_decisions').width()+'px');
59 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 77 })(jQuery)
62 78  
63 79 function change_task_responsible(el) {
... ...
test/functional/tasks_controller_test.rb
... ... @@ -4,6 +4,7 @@ require &#39;tasks_controller&#39;
4 4 class TasksControllerTest < ActionController::TestCase
5 5  
6 6 self.default_params = {profile: 'testuser'}
  7 +
7 8 def setup
8 9 @controller = TasksController.new
9 10 @request = ActionController::TestRequest.new
... ... @@ -27,6 +28,37 @@ class TasksControllerTest &lt; ActionController::TestCase
27 28 assert assigns(:tasks)
28 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 62 should 'list pending tasks without spam' do
31 63 requestor = fast_create(Person)
32 64 task_spam = Task.create!(:requestor => requestor, :target => profile, :spam => true)
... ... @@ -437,13 +469,13 @@ class TasksControllerTest &lt; ActionController::TestCase
437 469 t2 = CleanHouse.create!(:requestor => requestor, :target => profile)
438 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 474 assert_includes assigns(:tasks), t1
443 475 assert_not_includes assigns(:tasks), t2
444 476 assert_not_includes assigns(:tasks), t3
445 477  
446   - get :index
  478 + post :index
447 479  
448 480 assert_includes assigns(:tasks), t1
449 481 assert_includes assigns(:tasks), t2
... ...