mirror of
https://github.com/meineerde/redmine.git
synced 2026-02-01 03:57:15 +00:00
Some fixes for r20321:
* Include only visible issues in subtasks stats * Get subtasks using only one query * Show all subtasks count as badge * Add tests Patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@20718 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
4d3dec2dc0
commit
6bca099013
@ -143,6 +143,52 @@ module IssuesHelper
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
# Renders descendants stats (total descendants (open - closed)) with query links
|
||||
def render_descendants_stats(issue)
|
||||
# Get issue descendants grouped by status type (open/closed) using a single query
|
||||
subtasks_grouped = issue.descendants.visible.joins(:status).select(:is_closed, :id).group(:is_closed).reorder(:is_closed).count(:id)
|
||||
# Cast keys to boolean in order to have consistent results between database types
|
||||
subtasks_grouped.transform_keys! {|k| ActiveModel::Type::Boolean.new.cast(k)}
|
||||
|
||||
open_subtasks = subtasks_grouped[false].to_i
|
||||
closed_subtasks = subtasks_grouped[true].to_i
|
||||
all_subtasks = open_subtasks + closed_subtasks
|
||||
|
||||
return if all_subtasks == 0
|
||||
|
||||
all_block = content_tag(
|
||||
'span',
|
||||
link_to(all_subtasks, issues_path(parent_id: "~#{issue.id}", set_filter: true, status_id: '*')),
|
||||
class: 'badge badge-issues-count'
|
||||
)
|
||||
|
||||
closed_block = content_tag(
|
||||
'span',
|
||||
link_to_if(
|
||||
closed_subtasks > 0,
|
||||
l(:label_x_closed_issues_abbr, count: closed_subtasks),
|
||||
issues_path(parent_id: "~#{issue.id}", set_filter: true, status_id: 'c')
|
||||
),
|
||||
class: 'closed'
|
||||
)
|
||||
|
||||
open_block = content_tag(
|
||||
'span',
|
||||
link_to_if(
|
||||
open_subtasks > 0,
|
||||
l(:label_x_open_issues_abbr, :count => open_subtasks),
|
||||
issues_path(:parent_id => "~#{issue.id}", :set_filter => true, :status_id => 'o')
|
||||
),
|
||||
class: 'open'
|
||||
)
|
||||
|
||||
content_tag(
|
||||
'span',
|
||||
"#{all_block} (#{open_block} — #{closed_block})".html_safe,
|
||||
:class => 'issues-stat'
|
||||
)
|
||||
end
|
||||
|
||||
# Renders the list of related issues on the issue details view
|
||||
def render_issue_relations(issue, relations)
|
||||
manage_relations = User.current.allowed_to?(:manage_issue_relations, issue.project)
|
||||
|
||||
@ -109,18 +109,8 @@ end %>
|
||||
<%= link_to_new_subtask(@issue) if User.current.allowed_to?(:manage_subtasks, @project) %>
|
||||
</div>
|
||||
<p>
|
||||
<strong><%=l(:label_subtask_plural)%></strong>
|
||||
<% if !@issue.leaf? %>
|
||||
(<%= link_to(l(:label_x_issues, :count => @issue.descendants.count),
|
||||
issues_path(:parent_id => "~#{@issue.id}", :set_filter => true, :status_id => '*')) %>
|
||||
: <%= link_to_if( @issue.descendants.select(&:closed?).count > 0,
|
||||
l(:label_x_closed_issues_abbr, :count => @issue.descendants.select(&:closed?).count ),
|
||||
issues_path(:parent_id => "~#{@issue.id}", :set_filter => true, :status_id => 'c')) %>
|
||||
—
|
||||
<%= link_to_if( @issue.descendants.open.count > 0,
|
||||
l(:label_x_open_issues_abbr, :count => @issue.descendants.open.count ),
|
||||
issues_path(:parent_id => "~#{@issue.id}", :set_filter => true, :status_id => 'o')) %>)
|
||||
<% end %>
|
||||
<strong><%=l(:label_subtask_plural)%></strong>
|
||||
<%= render_descendants_stats(@issue) unless @issue.leaf? %>
|
||||
</p>
|
||||
<%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do %>
|
||||
<%= render_descendants_tree(@issue) unless @issue.leaf? %>
|
||||
|
||||
@ -540,6 +540,8 @@ body.controller-issues h2.inline-flex {padding-right: 0}
|
||||
#issue_tree td.checkbox, #relations td.checkbox {display:none;}
|
||||
#issue_tree td.subject, #relations td.subject {width: 50%;}
|
||||
#issue_tree td.buttons, #relations td.buttons {padding:0;}
|
||||
#issue_tree .issues-stat {font-size: 80%}
|
||||
#issue_tree .issues-stat .badge {bottom: initial;}
|
||||
|
||||
#trackers_description {display:none;}
|
||||
#trackers_description dt {font-weight: bold; text-decoration: underline;}
|
||||
@ -1470,6 +1472,10 @@ td.gantt_selected_column .gantt_hdr,.gantt_selected_column_container {
|
||||
color: #1D781D;
|
||||
border: 1px solid #1D781D;
|
||||
}
|
||||
.badge-issues-count {
|
||||
background: #EEEEEE;
|
||||
}
|
||||
|
||||
/***** Tooltips *****/
|
||||
.ui-tooltip {
|
||||
background: #000;
|
||||
|
||||
@ -2340,6 +2340,54 @@ class IssuesControllerTest < Redmine::ControllerTest
|
||||
end
|
||||
end
|
||||
|
||||
def test_show_should_show_subtasks_stats
|
||||
@request.session[:user_id] = 1
|
||||
child1 = Issue.generate!(parent_issue_id: 1, subject: 'Open child issue')
|
||||
Issue.generate!(parent_issue_id: 1, subject: 'Closed child issue', status_id: 5)
|
||||
Issue.generate!(parent_issue_id: child1.id, subject: 'Open child of child')
|
||||
# Issue not visible for anonymous
|
||||
Issue.generate!(parent_issue_id: 1, subject: 'Private child', project_id: 5)
|
||||
|
||||
get(:show, params: {:id => 1})
|
||||
assert_response :success
|
||||
|
||||
assert_select 'div#issue_tree span.issues-stat' do
|
||||
assert_select 'span.badge', text: '4'
|
||||
assert_select 'span.open a', text: '3 open'
|
||||
assert_equal CGI.unescape(css_select('span.open a').first.attr('href')),
|
||||
"/issues?parent_id=~1&set_filter=true&status_id=o"
|
||||
|
||||
assert_select 'span.closed a', text: '1 closed'
|
||||
assert_equal CGI.unescape(css_select('span.closed a').first.attr('href')),
|
||||
"/issues?parent_id=~1&set_filter=true&status_id=c"
|
||||
end
|
||||
end
|
||||
|
||||
def test_show_subtasks_stats_should_not_link_if_issue_has_zero_open_or_closed_subtasks
|
||||
child1 = Issue.generate!(parent_issue_id: 1, subject: 'Open child issue')
|
||||
|
||||
get(:show, params: {:id => 1})
|
||||
assert_response :success
|
||||
|
||||
assert_select 'div#issue_tree span.issues-stat' do
|
||||
assert_select 'span.open a', text: '1 open'
|
||||
assert_equal CGI.unescape(css_select('span.open a').first.attr('href')),
|
||||
"/issues?parent_id=~1&set_filter=true&status_id=o"
|
||||
assert_select 'span.closed', text: '0 closed'
|
||||
assert_select 'span.closed a', 0
|
||||
end
|
||||
end
|
||||
|
||||
def test_show_should_not_show_subtasks_stats_if_subtasks_are_not_visible
|
||||
# Issue not visible for anonymous
|
||||
Issue.generate!(parent_issue_id: 1, subject: 'Private child', project_id: 5)
|
||||
|
||||
get(:show, params: {:id => 1})
|
||||
assert_response :success
|
||||
|
||||
assert_select 'div#issue_tree span.issues-stat', 0
|
||||
end
|
||||
|
||||
def test_show_should_list_parents
|
||||
issue = Issue.
|
||||
create!(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user