Commit 13635dd88d20397838dae40b6c6adadc733cf55a
1 parent
36dfeecb
Exists in
web_steps_improvements
and in
6 other branches
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>
Showing
5 changed files
with
78 additions
and
27 deletions
Show diff stats
app/controllers/my_profile/tasks_controller.rb
| ... | ... | @@ -14,16 +14,15 @@ class TasksController < 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 < 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 < 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 'tasks_controller' |
| 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 < 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 < 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 | ... | ... |