Commit f34aaed3e0f800585fd808bbdee46089d5f3b21a

Authored by Augusto_Serpro
2 parents 02798bcc af36638d

Merge branch 'tasks_text_filter' into stable

app/controllers/my_profile/tasks_controller.rb
@@ -3,9 +3,10 @@ class TasksController < MyProfileController @@ -3,9 +3,10 @@ class TasksController < MyProfileController
3 protect 'perform_task', :profile 3 protect 'perform_task', :profile
4 4
5 def index 5 def index
6 - @filter = params[:filter_type].blank? ? nil : params[:filter_type] 6 + @filter_type = params[:filter_type] = params[:filter_type].blank? ? nil : params[:filter_type]
  7 + @filter_text = params[:filter_text].blank? ? nil : params[:filter_text]
7 @task_types = Task.pending_types_for(profile) 8 @task_types = Task.pending_types_for(profile)
8 - @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) 9 + @tasks = Task.pending_all(profile,params).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
9 @failed = params ? params[:failed] : {} 10 @failed = params ? params[:failed] : {}
10 end 11 end
11 12
@@ -65,4 +66,12 @@ class TasksController < MyProfileController @@ -65,4 +66,12 @@ class TasksController < MyProfileController
65 @ticket = Ticket.find(:first, :conditions => ['(requestor_id = ? or target_id = ?) and id = ?', profile.id, profile.id, params[:id]]) 66 @ticket = Ticket.find(:first, :conditions => ['(requestor_id = ? or target_id = ?) and id = ?', profile.id, profile.id, params[:id]])
66 end 67 end
67 68
  69 + def search_tasks
  70 +
  71 + params[:filter_type] = params[:filter_type].blank? ? nil : params[:filter_type]
  72 + result = Task.pending_all(profile,params)
  73 +
  74 + render :json => result.map { |task| {:label => task.data[:name], :value => task.data[:name]} }
  75 + end
  76 +
68 end 77 end
app/models/task.rb
@@ -239,6 +239,10 @@ class Task < ActiveRecord::Base @@ -239,6 +239,10 @@ class Task < ActiveRecord::Base
239 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] } 239 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] }
240 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } 240 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} }
241 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } 241 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} }
  242 + scope :like, ->(field,value) { where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value}
  243 + scope :pending_all, ->(profile, params){
  244 + self.to(profile).without_spam.pending.of(params[:filter_type]).like('data', params[:filter_text])
  245 + }
242 246
243 scope :to, lambda { |profile| 247 scope :to, lambda { |profile|
244 environment_condition = nil 248 environment_condition = nil
@@ -250,6 +254,7 @@ class Task < ActiveRecord::Base @@ -250,6 +254,7 @@ class Task < ActiveRecord::Base
250 { :conditions => [environment_condition, profile_condition].compact.join(' OR ') } 254 { :conditions => [environment_condition, profile_condition].compact.join(' OR ') }
251 } 255 }
252 256
  257 +
253 def self.pending_types_for(profile) 258 def self.pending_types_for(profile)
254 Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] } 259 Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] }
255 end 260 end
app/views/tasks/index.html.erb
@@ -21,11 +21,24 @@ @@ -21,11 +21,24 @@
21 </div> 21 </div>
22 <% end %> 22 <% end %>
23 23
  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 %>
  37 +<% end %>
24 <% if @tasks.empty? %> 38 <% if @tasks.empty? %>
25 <p> 39 <p>
26 - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => 'document.location.href = "?filter_type="+this.value')%> 40 + <em><%= _('No pending tasks for %s') % profile.name %></em>
27 </p> 41 </p>
28 - <em><%= _('No pending tasks for %s') % profile.name %></em>  
29 <% else %> 42 <% else %>
30 <%= form_tag :action => 'close' do%> 43 <%= form_tag :action => 'close' do%>
31 <% button_bar do %> 44 <% button_bar do %>
@@ -38,14 +51,14 @@ @@ -38,14 +51,14 @@
38 51
39 <ul class='task-list'> 52 <ul class='task-list'>
40 <p> 53 <p>
41 - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => "document.location.href = '?filter_type='+this.value") %>  
42 - </p>  
43 - <p>  
44 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %> 54 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
45 </p> 55 </p>
46 - <% @tasks.each do |task| %>  
47 - <%= render :partial => 'task', :locals => { :task => task } %>  
48 - <% end %> 56 +
  57 + <div class="task_boxes">
  58 + <% @tasks.each do |task| %>
  59 + <%= render :partial => 'task', :locals => { :task => task } %>
  60 + <% end %>
  61 + </div>
49 <p> 62 <p>
50 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %> 63 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
51 </p> 64 </p>
public/javascripts/tasks.js
@@ -45,5 +45,21 @@ @@ -45,5 +45,21 @@
45 $('.task_title').css('margin-right', $('.task_decisions').width()+'px'); 45 $('.task_title').css('margin-right', $('.task_decisions').width()+'px');
46 $('.task_title').css('margin-left', $('.task_arrow').width()+'px'); 46 $('.task_title').css('margin-left', $('.task_arrow').width()+'px');
47 47
  48 + //Autocomplete tasks by type
  49 + $('#filter-text-autocomplete').autocomplete({
  50 + source:function(request,response){
  51 + $.ajax({
  52 + url:document.location.pathname+'/search_tasks',
  53 + dataType:'json',
  54 + data:{
  55 + filter_text:request.term,
  56 + filter_type:jQuery('#filter-type').val()
  57 + },
  58 + success:response
  59 + })
  60 + },
  61 + minLength:2
  62 + });
  63 +
48 })(jQuery) 64 })(jQuery)
49 65
public/stylesheets/application.css
@@ -6726,6 +6726,10 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6726,6 +6726,10 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6726 6726
6727 /* AutoComplete*/ 6727 /* AutoComplete*/
6728 .formfield input.ui-autocomplete-loading { background: url('/images/loading-small.gif') right center no-repeat, url("../images/input-bg.gif") no-repeat left top; } 6728 .formfield input.ui-autocomplete-loading { background: url('/images/loading-small.gif') right center no-repeat, url("../images/input-bg.gif") no-repeat left top; }
  6729 +.ui-autocomplete-loading{
  6730 + background: url('/images/loading-small.gif') right center no-repeat
  6731 +}
  6732 +
6729 6733
6730 .ui-autocomplete-category { 6734 .ui-autocomplete-category {
6731 font-weight: bold; 6735 font-weight: bold;
test/functional/tasks_controller_test.rb
@@ -5,7 +5,7 @@ class TasksController; def rescue_action(e) raise e end; end @@ -5,7 +5,7 @@ class TasksController; def rescue_action(e) raise e end; end
5 5
6 class TasksControllerTest < ActionController::TestCase 6 class TasksControllerTest < ActionController::TestCase
7 7
8 - noosfero_test :profile => 'testuser' 8 + noosfero_test :profile => 'testuser'
9 9
10 def setup 10 def setup
11 @controller = TasksController.new 11 @controller = TasksController.new
@@ -30,6 +30,37 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -30,6 +30,37 @@ class TasksControllerTest &lt; ActionController::TestCase
30 assert assigns(:tasks) 30 assert assigns(:tasks)
31 end 31 end
32 32
  33 + should 'get filtered tasks to autocomplete text field' do
  34 +
  35 + #Create a admin user and a simple user
  36 + profile_admin = create_user('admin_tester').person
  37 + Environment.default.add_admin(profile_admin)
  38 + user = fast_create(Person,:name => 'FakeUser')
  39 +
  40 + #Create a task of type 'ModerateUserRegistration'
  41 + task_data = {
  42 + :target => Environment.default,
  43 + :spam => false,
  44 + :data => {:user_id => user.id,:name => user.name}
  45 + }
  46 + ModerateUserRegistration.create!(task_data)
  47 +
  48 + #Use admin user to your profile with a pending task above
  49 + @controller.stubs(:profile).returns(profile_admin)
  50 + login_as profile_admin.identifier
  51 +
  52 + #Perform a http request to 'search_task' action with params
  53 + post :search_tasks, :filter_type =>'ModerateUserRegistration', :filter_text => 'Fak'
  54 +
  55 + assert_response :success
  56 +
  57 + #Check if json response matches with a 'FakeUser'
  58 + json_response = ActiveSupport::JSON.decode(@response.body)
  59 + value = json_response[0]['value']
  60 +
  61 + assert_equal value, 'FakeUser'
  62 + end
  63 +
33 should 'list pending tasks without spam' do 64 should 'list pending tasks without spam' do
34 requestor = fast_create(Person) 65 requestor = fast_create(Person)
35 task_spam = Task.create!(:requestor => requestor, :target => profile, :spam => true) 66 task_spam = Task.create!(:requestor => requestor, :target => profile, :spam => true)
@@ -346,6 +377,28 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -346,6 +377,28 @@ class TasksControllerTest &lt; ActionController::TestCase
346 assert_includes assigns(:tasks), t3 377 assert_includes assigns(:tasks), t3
347 end 378 end
348 379
  380 + should 'filter tasks by type and data content' do
  381 + class CleanHouse < Task; end
  382 + class FeedDog < Task; end
  383 + Task.stubs(:per_page).returns(3)
  384 + requestor = fast_create(Person)
  385 + t1 = CleanHouse.create!(:requestor => requestor, :target => profile, :data => {:name => 'Task Test'})
  386 + t2 = CleanHouse.create!(:requestor => requestor, :target => profile)
  387 + t3 = FeedDog.create!(:requestor => requestor, :target => profile)
  388 +
  389 + post :index, :filter_type => t1.type, :filter_text => 'test'
  390 +
  391 + assert_includes assigns(:tasks), t1
  392 + assert_not_includes assigns(:tasks), t2
  393 + assert_not_includes assigns(:tasks), t3
  394 +
  395 + post :index
  396 +
  397 + assert_includes assigns(:tasks), t1
  398 + assert_includes assigns(:tasks), t2
  399 + assert_includes assigns(:tasks), t3
  400 + end
  401 +
349 should 'return tasks ordered accordingly and limited by pages' do 402 should 'return tasks ordered accordingly and limited by pages' do
350 time = Time.now 403 time = Time.now
351 person = fast_create(Person) 404 person = fast_create(Person)