summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2016-08-20 10:27:39 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2016-08-20 10:27:39 +0000
commit3539cfcf0f6e9f4379c5a15ae610608b370ee23c (patch)
treeebdef3f7b0fbcd6fadb20b75098e2d208b6f310d /app
parenta78c7249029828685173ecd86151fb80546d3032 (diff)
downloadredmine-3539cfcf0f6e9f4379c5a15ae610608b370ee23c.tar.gz
redmine-3539cfcf0f6e9f4379c5a15ae610608b370ee23c.zip
Adds issue tracker and status columns and filters on spent time list (#23401).
git-svn-id: http://svn.redmine.org/redmine/trunk@15738 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app')
-rw-r--r--app/controllers/timelog_controller.rb1
-rw-r--r--app/models/query.rb20
-rw-r--r--app/models/time_entry_query.rb42
-rw-r--r--app/views/timelog/_list.html.erb2
4 files changed, 60 insertions, 5 deletions
diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb
index 2c72f49c6..93051fd66 100644
--- a/app/controllers/timelog_controller.rb
+++ b/app/controllers/timelog_controller.rb
@@ -45,7 +45,6 @@ class TimelogController < ApplicationController
sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
sort_update(@query.sortable_columns)
scope = time_entry_scope(:order => sort_clause).
- includes(:project, :user, :issue).
preload(:issue => [:project, :tracker, :status, :assigned_to, :priority])
respond_to do |format|
diff --git a/app/models/query.rb b/app/models/query.rb
index 9a1dc0d5a..fdfe8ec7e 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -74,6 +74,26 @@ class QueryColumn
end
end
+class QueryAssociationColumn < QueryColumn
+
+ def initialize(association, attribute, options={})
+ @association = association
+ @attribute = attribute
+ name_with_assoc = "#{association}.#{attribute}".to_sym
+ super(name_with_assoc, options)
+ end
+
+ def value_object(object)
+ if assoc = object.send(@association)
+ assoc.send @attribute
+ end
+ end
+
+ def css_classes
+ @css_classes ||= "#{@association}-#{@attribute}"
+ end
+end
+
class QueryCustomFieldColumn < QueryColumn
def initialize(custom_field, options={})
diff --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb
index eefee0eb4..5d0bdee3b 100644
--- a/app/models/time_entry_query.rb
+++ b/app/models/time_entry_query.rb
@@ -27,6 +27,8 @@ class TimeEntryQuery < Query
QueryColumn.new(:user, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
QueryColumn.new(:activity, :sortable => "#{TimeEntryActivity.table_name}.position", :groupable => true),
QueryColumn.new(:issue, :sortable => "#{Issue.table_name}.id"),
+ QueryAssociationColumn.new(:issue, :tracker, :caption => :field_tracker, :sortable => "#{Tracker.table_name}.position"),
+ QueryAssociationColumn.new(:issue, :status, :caption => :field_status, :sortable => "#{IssueStatus.table_name}.position"),
QueryColumn.new(:comments),
QueryColumn.new(:hours, :sortable => "#{TimeEntry.table_name}.hours", :totalable => true),
]
@@ -71,6 +73,14 @@ class TimeEntryQuery < Query
end
add_available_filter("issue_id", :type => :tree, :label => :label_issue)
+ add_available_filter("issue.tracker_id",
+ :type => :list,
+ :name => l("label_attribute_of_issue", :name => l(:field_tracker)),
+ :values => Tracker.sorted.map {|t| [t.name, t.id.to_s]})
+ add_available_filter("issue.status_id",
+ :type => :list,
+ :name => l("label_attribute_of_issue", :name => l(:field_status)),
+ :values => IssueStatus.sorted.map {|s| [s.name, s.id.to_s]})
add_available_filter("issue.fixed_version_id",
:type => :list,
:name => l("label_attribute_of_issue", :name => l(:field_fixed_version)),
@@ -118,14 +128,16 @@ class TimeEntryQuery < Query
end
def base_scope
- TimeEntry.visible.where(statement)
+ TimeEntry.visible.
+ joins(:project, :user).
+ joins("LEFT OUTER JOIN issues ON issues.id = time_entries.issue_id").
+ where(statement)
end
def results_scope(options={})
order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
- TimeEntry.visible.
- where(statement).
+ base_scope.
order(order_option).
joins(joins_for_order_statement(order_option.join(','))).
includes(:activity).
@@ -185,6 +197,14 @@ class TimeEntryQuery < Query
end
end
+ def sql_for_issue_tracker_id_field(field, operator, value)
+ sql_for_field("tracker_id", operator, value, Issue.table_name, "tracker_id")
+ end
+
+ def sql_for_issue_status_id_field(field, operator, value)
+ sql_for_field("status_id", operator, value, Issue.table_name, "status_id")
+ end
+
# Accepts :from/:to params as shortcut filters
def build_from_params(params)
super
@@ -197,4 +217,20 @@ class TimeEntryQuery < Query
end
self
end
+
+ def joins_for_order_statement(order_options)
+ joins = [super]
+
+ if order_options
+ if order_options.include?('issue_statuses')
+ joins << "LEFT OUTER JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{Issue.table_name}.status_id"
+ end
+ if order_options.include?('trackers')
+ joins << "LEFT OUTER JOIN #{Tracker.table_name} ON #{Tracker.table_name}.id = #{Issue.table_name}.tracker_id"
+ end
+ end
+
+ joins.compact!
+ joins.any? ? joins.join(' ') : nil
+ end
end
diff --git a/app/views/timelog/_list.html.erb b/app/views/timelog/_list.html.erb
index 3a854ccef..be02adb5c 100644
--- a/app/views/timelog/_list.html.erb
+++ b/app/views/timelog/_list.html.erb
@@ -31,7 +31,7 @@
</td>
</tr>
<% end %>
- <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
+ <tr id="time-entry-<%= entry.id %>" class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
<td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
<%= raw @query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, entry)}</td>"}.join %>
<td class="buttons">