Commit be57a4050be19d053602329cdb690a0c34cb71f5
Committed by
Marcos Pereira
1 parent
27f11bf7
Exists in
send_email_to_admins
and in
5 other branches
Improves listing of processed tasks
- Filters for processed tasks Signed-off-by: Gustavo Jaruga <darksshades@gmail.com> Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>
Showing
7 changed files
with
178 additions
and
11 deletions
Show diff stats
app/controllers/my_profile/tasks_controller.rb
@@ -26,7 +26,11 @@ class TasksController < MyProfileController | @@ -26,7 +26,11 @@ class TasksController < MyProfileController | ||
26 | end | 26 | end |
27 | 27 | ||
28 | def processed | 28 | def processed |
29 | - @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at) | 29 | + @tasks = Task.to(profile).without_spam.closed.order('tasks.created_at DESC') |
30 | + @filter = params[:filter] || {} | ||
31 | + @tasks = filter_tasks(@filter, @tasks) | ||
32 | + @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page]) | ||
33 | + @task_types = Task.closed_types_for(profile) | ||
30 | end | 34 | end |
31 | 35 | ||
32 | def change_responsible | 36 | def change_responsible |
@@ -102,4 +106,37 @@ class TasksController < MyProfileController | @@ -102,4 +106,37 @@ class TasksController < MyProfileController | ||
102 | render :json => result.map { |task| {:label => task.data[:name], :value => task.data[:name]} } | 106 | render :json => result.map { |task| {:label => task.data[:name], :value => task.data[:name]} } |
103 | end | 107 | end |
104 | 108 | ||
109 | + protected | ||
110 | + | ||
111 | + def filter_by_closed_date(filter, tasks) | ||
112 | + filter[:closed_from] = Date.parse(filter[:closed_from]) unless filter[:closed_from].blank? | ||
113 | + filter[:closed_until] = Date.parse(filter[:closed_until]) unless filter[:closed_until].blank? | ||
114 | + | ||
115 | + tasks = tasks.where('tasks.end_date >= ?', filter[:closed_from].beginning_of_day) unless filter[:closed_from].blank? | ||
116 | + tasks = tasks.where('tasks.end_date <= ?', filter[:closed_until].end_of_day) unless filter[:closed_until].blank? | ||
117 | + tasks | ||
118 | + end | ||
119 | + | ||
120 | + def filter_by_creation_date(filter, tasks) | ||
121 | + filter[:created_from] = Date.parse(filter[:created_from]) unless filter[:created_from].blank? | ||
122 | + filter[:created_until] = Date.parse(filter[:created_until]) unless filter[:created_until].blank? | ||
123 | + | ||
124 | + tasks = tasks.where('tasks.created_at >= ?', filter[:created_from].beginning_of_day) unless filter[:created_from].blank? | ||
125 | + tasks = tasks.where('tasks.created_at <= ?', filter[:created_until].end_of_day) unless filter[:created_until].blank? | ||
126 | + tasks | ||
127 | + end | ||
128 | + | ||
129 | + def filter_tasks(filter, tasks) | ||
130 | + tasks = tasks.eager_load(:requestor, :closed_by) | ||
131 | + tasks = tasks.of(filter[:type].presence) | ||
132 | + tasks = tasks.where(:status => filter[:status]) unless filter[:status].blank? | ||
133 | + tasks = filter_by_creation_date(filter, tasks) | ||
134 | + tasks = filter_by_closed_date(filter, tasks) | ||
135 | + | ||
136 | + tasks = tasks.where('profiles.name LIKE ?', filter[:requestor]) unless filter[:requestor].blank? | ||
137 | + tasks = tasks.where('closed_bies_tasks.name LIKE ?', filter[:closed_by]) unless filter[:closed_by].blank? | ||
138 | + tasks = tasks.where('tasks.data LIKE ?', "%#{filter[:text]}%") unless filter[:text].blank? | ||
139 | + tasks | ||
140 | + end | ||
141 | + | ||
105 | end | 142 | end |
app/models/task.rb
@@ -329,6 +329,10 @@ class Task < ActiveRecord::Base | @@ -329,6 +329,10 @@ class Task < ActiveRecord::Base | ||
329 | 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] } |
330 | end | 330 | end |
331 | 331 | ||
332 | + def self.closed_types_for(profile) | ||
333 | + Task.to(profile).closed.select('distinct type').map { |t| [t.class.name, t.title] } | ||
334 | + end | ||
335 | + | ||
332 | def opened? | 336 | def opened? |
333 | status == Task::Status::ACTIVE || status == Task::Status::HIDDEN | 337 | status == Task::Status::ACTIVE || status == Task::Status::HIDDEN |
334 | end | 338 | end |
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +<div class="title"> | ||
2 | + <%= task_information(task) %> | ||
3 | +</div> | ||
4 | +<div class="status"> | ||
5 | + <%= _(Task::Status.names[task.status]) %> | ||
6 | +</div> | ||
7 | +<div class="dates"> | ||
8 | + <span class="created"> | ||
9 | + <span class="label"><%= _('Created:') %></span> | ||
10 | + <span class="value"><%= show_date(task.created_at) %></span> | ||
11 | + </span> | ||
12 | + — | ||
13 | + <span class="processed"> | ||
14 | + <span class="label"><%= _('Processed:') %></span> | ||
15 | + <span class="value"><%= show_date(task.end_date) %></span> | ||
16 | + </span> | ||
17 | +</div> | ||
18 | +<% if task.closed_by.present? %> | ||
19 | + <div class="closed-by"> | ||
20 | + <span class="label"><%= _('Closed by:') %></span> | ||
21 | + <span class="value"><%= link_to(task.closed_by.name, task.closed_by.url) %></span> | ||
22 | + </div> | ||
23 | +<% end %> |
app/views/tasks/index.html.erb
@@ -57,7 +57,9 @@ | @@ -57,7 +57,9 @@ | ||
57 | <% end %> | 57 | <% end %> |
58 | 58 | ||
59 | <div class="task_boxes"> | 59 | <div class="task_boxes"> |
60 | - <%= render :partial => 'task', :collection => @tasks %> | 60 | + <% @tasks.each do |task| %> |
61 | + <%= render :partial => partial_for_class(task.class, nil, nil), :locals => {:task => task} %> | ||
62 | + <% end %> | ||
61 | </div> | 63 | </div> |
62 | 64 | ||
63 | <% unless @view_only %> | 65 | <% unless @view_only %> |
app/views/tasks/processed.html.erb
1 | +<%= stylesheet_link_tag 'tasks' %> | ||
2 | + | ||
3 | +<div class="task-processed"> | ||
1 | <h1><%= _("%s's processed tasks") % profile.name %></h1> | 4 | <h1><%= _("%s's processed tasks") % profile.name %></h1> |
2 | 5 | ||
6 | +<div class="task-processed-filter"> | ||
7 | +<% | ||
8 | + type_collection = [[nil, _('All')]] + @task_types | ||
9 | +%> | ||
10 | + <%= form_tag '#', :method => 'get' do %> | ||
11 | + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %> | ||
12 | + <div> | ||
13 | + <%= labelled_select(_('Type of task')+': ', 'filter[type]', :first, :last, @filter[:type], type_collection, {:id => 'filter-type'}) %> | ||
14 | + <%= labelled_select(_('Status:'), 'filter[status]', :last, :first, @filter[:status], [[_('Any'), nil], [_(Task::Status.names[Task::Status::CANCELLED]), 2], [_(Task::Status.names[Task::Status::FINISHED]), 3] ]) %> | ||
15 | + </div> | ||
16 | + | ||
17 | + <div> | ||
18 | + <%= labelled_text_field(_('Text Filter:'), 'filter[text]', @filter[:text]) %> | ||
19 | + </div> | ||
20 | + | ||
21 | + <div> | ||
22 | + <%= labelled_text_field(_('Requestor:'), 'filter[requestor]', @filter[:requestor]) %> | ||
23 | + <%= labelled_text_field(_('Closed by:'), 'filter[closed_by]', @filter[:closed_by]) %> | ||
24 | + </div> | ||
25 | + <%= labelled_form_field(_('Creation date'), date_range_field('filter[created_from]', 'filter[created_until]', @filter[:created_from], @filter[:created_until], { :change_month => true, :change_year => true, :date_format => 'yy-mm-dd' }, { :size => 14, :from_id => 'filter_created_from', :to_id => 'filter_created_until' })) %> | ||
26 | + <%= labelled_form_field(_('Processed date'), date_range_field('filter[closed_from]', 'filter[closed_until]', @filter[:closed_from], @filter[:closed_until], { :change_month => true, :change_year => true, :date_format => 'yy-mm-dd' }, { :size => 14, :from_id => 'filter_closed_from', :to_id => 'filter_closed_until' })) %> | ||
27 | + | ||
28 | + <div class="actions"> | ||
29 | + <%= submit_button(:search, _('Search')) %> | ||
30 | + </div> | ||
31 | + <% end %> | ||
32 | + <% end %> | ||
33 | +</div> | ||
34 | + | ||
3 | <p> | 35 | <p> |
4 | <% if @tasks.empty? %> | 36 | <% if @tasks.empty? %> |
5 | <em><%= _('No processed tasks.') %></em> | 37 | <em><%= _('No processed tasks.') %></em> |
6 | <% else %> | 38 | <% else %> |
7 | - <ul> | 39 | + <ul class="task-list"> |
8 | <% @tasks.each do |item| %> | 40 | <% @tasks.each do |item| %> |
9 | - <li> | ||
10 | - <strong><%= task_information(item) %></strong> <br/> | ||
11 | - <small> | ||
12 | - <%= _('Created:') +' '+ show_date(item.created_at) %> | ||
13 | - — | ||
14 | - <%= _('Processed:') +' '+ show_date(item.end_date) %> | ||
15 | - </small> | 41 | + <li class="task status-<%= item.status%>"> |
42 | + <%= render :partial => partial_for_class(item.class, nil, 'processed'), :locals => {:task => item} %> | ||
16 | </li> | 43 | </li> |
17 | <% end %> | 44 | <% end %> |
18 | </ul> | 45 | </ul> |
46 | + <%= pagination_links(@tasks)%> | ||
19 | <% end %> | 47 | <% end %> |
20 | </p> | 48 | </p> |
21 | 49 | ||
22 | <% button_bar do %> | 50 | <% button_bar do %> |
23 | <%= button(:back, _('Back'), :action => 'index') %> | 51 | <%= button(:back, _('Back'), :action => 'index') %> |
24 | <% end %> | 52 | <% end %> |
53 | + | ||
54 | +</div> |
public/stylesheets/tasks.scss
@@ -82,3 +82,47 @@ div.pending-tasks { | @@ -82,3 +82,47 @@ div.pending-tasks { | ||
82 | .task_responsible { | 82 | .task_responsible { |
83 | text-align: right; | 83 | text-align: right; |
84 | } | 84 | } |
85 | + | ||
86 | +.task-processed li { | ||
87 | + background-color: rgb(240, 240, 240); | ||
88 | + border-radius: 8px; | ||
89 | + margin: 10px 0; | ||
90 | + list-style-type: none; | ||
91 | + padding: 12px; | ||
92 | +} | ||
93 | + | ||
94 | +.task-processed .task.status-3 { | ||
95 | + background-color: rgb(205, 252, 218); | ||
96 | +} | ||
97 | + | ||
98 | +.task-processed .task.status-2 { | ||
99 | + background-color: rgb(255, 203, 203); | ||
100 | +} | ||
101 | + | ||
102 | +.task-processed ul { | ||
103 | + padding: 0; | ||
104 | +} | ||
105 | + | ||
106 | +.task-processed .task-list .task .title { | ||
107 | + border-bottom: 1px solid rgba(0, 0, 0, 0.1); | ||
108 | + font-weight: bold; | ||
109 | + color: rgb(44, 44, 44); | ||
110 | +} | ||
111 | + | ||
112 | +.task-processed .task .status { | ||
113 | + float: right; | ||
114 | + color: rgb(156, 156, 156); | ||
115 | + font-weight: bold; | ||
116 | +} | ||
117 | + | ||
118 | +.task-processed .task .dates { | ||
119 | + font-size: 11px; | ||
120 | +} | ||
121 | + | ||
122 | +.task-processed .task .closed-by { | ||
123 | + font-size: 11px; | ||
124 | +} | ||
125 | + | ||
126 | +.task-processed .task .label { | ||
127 | + font-weight: bold | ||
128 | +} |
test/functional/tasks_controller_test.rb
@@ -75,7 +75,8 @@ class TasksControllerTest < ActionController::TestCase | @@ -75,7 +75,8 @@ class TasksControllerTest < ActionController::TestCase | ||
75 | 75 | ||
76 | assert_response :success | 76 | assert_response :success |
77 | assert_template 'processed' | 77 | assert_template 'processed' |
78 | - assert_kind_of Array, assigns(:tasks) | 78 | + assert !assigns(:tasks).nil? |
79 | + assert_kind_of ActiveRecord::Relation, assigns(:tasks) | ||
79 | end | 80 | end |
80 | 81 | ||
81 | should 'display task created_at' do | 82 | should 'display task created_at' do |
@@ -762,4 +763,30 @@ class TasksControllerTest < ActionController::TestCase | @@ -762,4 +763,30 @@ class TasksControllerTest < ActionController::TestCase | ||
762 | assert_equal [email_template], assigns(:rejection_email_templates) | 763 | assert_equal [email_template], assigns(:rejection_email_templates) |
763 | end | 764 | end |
764 | 765 | ||
766 | + should 'filter processed tasks by all filters' do | ||
767 | + requestor = fast_create(Person) | ||
768 | + closed_by = fast_create(Person) | ||
769 | + class AnotherTask < Task; end | ||
770 | + | ||
771 | + created_date = DateTime.now | ||
772 | + processed_date = DateTime.now | ||
773 | + | ||
774 | + task_params = {:status => Task::Status::FINISHED, :requestor => requestor, :target => profile, :created_at => created_date, :end_date => processed_date, :closed_by => closed_by, :data => {:field => 'some data field'}} | ||
775 | + | ||
776 | + task = create(AnotherTask, task_params) | ||
777 | + create(Task, task_params) | ||
778 | + create(AnotherTask, task_params.clone.merge(:status => Task::Status::CANCELLED)) | ||
779 | + create(AnotherTask, task_params.clone.merge(:created_at => created_date - 1.day)) | ||
780 | + create(AnotherTask, task_params.clone.merge(:created_at => created_date + 1.day)) | ||
781 | + create(AnotherTask, task_params.clone.merge(:end_date => processed_date - 1.day)) | ||
782 | + create(AnotherTask, task_params.clone.merge(:end_date => processed_date + 1.day)) | ||
783 | + create(AnotherTask, task_params.clone.merge(:requestor => fast_create(Person, :name => 'another-requestor'))) | ||
784 | + create(AnotherTask, task_params.clone.merge(:closed_by => fast_create(Person, :name => 'another-closer'))) | ||
785 | + create(AnotherTask, task_params.clone.merge(:data => {:field => "other data field"})) | ||
786 | + | ||
787 | + get :processed, :filter => {:type => AnotherTask, :status => Task::Status::FINISHED, :created_from => created_date, :created_until => created_date, :closed_from => processed_date, :closed_until => processed_date, :requestor => requestor.name, :closed_by => closed_by.name, :text => "some data field"} | ||
788 | + assert_response :success | ||
789 | + assert_equal [task], assigns(:tasks) | ||
790 | + end | ||
791 | + | ||
765 | end | 792 | end |