Feature #31589 » 0001-Show-warning-and-the-reason-when-the-issue-cannot-be.patch
| app/models/issue.rb | ||
|---|---|---|
| 56 | 56 | |
| 57 | 57 |
DONE_RATIO_OPTIONS = %w(issue_field issue_status) |
| 58 | 58 | |
| 59 |
attr_reader :transition_warning |
|
| 59 | 60 |
attr_writer :deleted_attachment_ids |
| 60 | 61 |
delegate :notes, :notes=, :private_notes, :private_notes=, :to => :current_journal, :allow_nil => true |
| 61 | 62 | |
| ... | ... | |
| 969 | 970 |
!relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil?
|
| 970 | 971 |
end |
| 971 | 972 | |
| 973 |
# Returns true if this issue can be closed and if not, returns false and populates the reason |
|
| 974 |
def closable? |
|
| 975 |
if descendants.open.any? |
|
| 976 |
@transition_warning = l(:notice_issue_not_closable_by_open_tasks) |
|
| 977 |
return false |
|
| 978 |
end |
|
| 979 |
if blocked? |
|
| 980 |
@transition_warning = l(:notice_issue_not_closable_by_blocking_issue) |
|
| 981 |
return false |
|
| 982 |
end |
|
| 983 |
return true |
|
| 984 |
end |
|
| 985 | ||
| 986 |
# Returns true if this issue can be reopen and if not, returns false and populates the reason |
|
| 987 |
def reopenable? |
|
| 988 |
if ancestors.open(false).any? |
|
| 989 |
@transition_warning = l(:notice_issue_not_reopenable_by_closed_parent_issue) |
|
| 990 |
return false |
|
| 991 |
end |
|
| 992 |
return true |
|
| 993 |
end |
|
| 994 | ||
| 972 | 995 |
# Returns the default status of the issue based on its tracker |
| 973 | 996 |
# Returns nil if tracker is nil |
| 974 | 997 |
def default_status |
| ... | ... | |
| 1008 | 1031 |
statuses << default_status if include_default || (new_record? && statuses.empty?) |
| 1009 | 1032 | |
| 1010 | 1033 |
statuses = statuses.compact.uniq.sort |
| 1011 |
if blocked? || descendants.open.any?
|
|
| 1034 |
unless closable?
|
|
| 1012 | 1035 |
# cannot close a blocked issue or a parent with open subtasks |
| 1013 | 1036 |
statuses.reject!(&:is_closed?) |
| 1014 | 1037 |
end |
| 1015 |
if ancestors.open(false).any?
|
|
| 1038 |
unless reopenable?
|
|
| 1016 | 1039 |
# cannot reopen a subtask of a closed parent |
| 1017 | 1040 |
statuses.select!(&:is_closed?) |
| 1018 | 1041 |
end |
| app/views/issues/_attributes.html.erb | ||
|---|---|---|
| 3 | 3 |
<div class="splitcontent"> |
| 4 | 4 |
<div class="splitcontentleft"> |
| 5 | 5 |
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %>
|
| 6 |
<p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
|
|
| 7 |
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %></p>
|
|
| 6 |
<p> |
|
| 7 |
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
|
|
| 8 |
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %>
|
|
| 9 |
<% if @issue.transition_warning %> |
|
| 10 |
<span class="icon-only icon-warning" title="<%= @issue.transition_warning %>"><%= @issue.transition_warning %></span> |
|
| 11 |
<% end %> |
|
| 12 |
</p> |
|
| 8 | 13 |
<%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %> |
| 9 | 14 |
<% else %> |
| 10 | 15 |
<p><label><%= l(:field_status) %></label> <%= @issue.status %></p> |
| config/locales/en.yml | ||
|---|---|---|
| 191 | 191 |
notice_new_password_must_be_different: The new password must be different from the current password |
| 192 | 192 |
notice_import_finished: "%{count} items have been imported"
|
| 193 | 193 |
notice_import_finished_with_errors: "%{count} out of %{total} items could not be imported"
|
| 194 |
notice_issue_not_closable_by_open_tasks: "This issue cannot be closed because it has at least one open subtask." |
|
| 195 |
notice_issue_not_closable_by_blocking_issue: "This issue cannot be closed because it is blocked by at least one open issue." |
|
| 196 |
notice_issue_not_reopenable_by_closed_parent_issue: "This issue cannot be reopened because its parent issue is closed." |
|
| 194 | 197 | |
| 195 | 198 |
error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
|
| 196 | 199 |
error_scm_not_found: "The entry or revision was not found in the repository." |
| test/functional/issues_controller_test.rb | ||
|---|---|---|
| 5196 | 5196 |
assert_select 'select[name=?]', 'issue[priority_id]' do |
| 5197 | 5197 |
assert_select 'option[value="15"]', 0 |
| 5198 | 5198 |
end |
| 5199 |
assert_select 'span.icon-warning', 0 |
|
| 5199 | 5200 |
end |
| 5200 | 5201 | |
| 5201 | 5202 |
def test_edit_should_hide_project_if_user_is_not_allowed_to_change_project |
| ... | ... | |
| 5307 | 5308 |
end |
| 5308 | 5309 |
end |
| 5309 | 5310 | |
| 5311 |
def test_get_edit_for_issue_with_transition_warning_should_show_the_warning |
|
| 5312 |
@request.session[:user_id] = 2 |
|
| 5313 | ||
| 5314 |
get( |
|
| 5315 |
:edit, |
|
| 5316 |
:params => {
|
|
| 5317 |
:id => 9, |
|
| 5318 |
} |
|
| 5319 |
) |
|
| 5320 | ||
| 5321 |
assert_response :success |
|
| 5322 |
reason = l(:notice_issue_not_closable_by_blocking_issue) |
|
| 5323 |
assert_select 'span.icon-warning[title=?]', reason, :text => reason |
|
| 5324 |
end |
|
| 5325 | ||
| 5310 | 5326 |
def test_update_form_for_existing_issue |
| 5311 | 5327 |
@request.session[:user_id] = 2 |
| 5312 | 5328 |
patch( |
| test/unit/issue_test.rb | ||
|---|---|---|
| 2104 | 2104 |
child = Issue.generate!(:parent_issue_id => parent.id) |
| 2105 | 2105 | |
| 2106 | 2106 |
allowed_statuses = parent.reload.new_statuses_allowed_to(users(:users_002)) |
| 2107 | ||
| 2108 |
assert !parent.closable? |
|
| 2109 |
assert_equal l(:notice_issue_not_closable_by_open_tasks), parent.transition_warning |
|
| 2110 | ||
| 2107 | 2111 |
assert allowed_statuses.any? |
| 2108 | 2112 |
assert_equal [], allowed_statuses.select(&:is_closed?) |
| 2109 | 2113 |
end |
| ... | ... | |
| 2113 | 2117 |
child = Issue.generate!(:parent_issue_id => parent.id, :status_id => 5) |
| 2114 | 2118 | |
| 2115 | 2119 |
allowed_statuses = parent.reload.new_statuses_allowed_to(users(:users_002)) |
| 2120 | ||
| 2121 |
assert parent.closable? |
|
| 2122 |
assert_nil parent.transition_warning |
|
| 2116 | 2123 |
assert allowed_statuses.any? |
| 2117 | 2124 |
assert allowed_statuses.select(&:is_closed?).any? |
| 2118 | 2125 |
end |
| ... | ... | |
| 3244 | 3251 |
User.current = user_in_asia |
| 3245 | 3252 |
assert issue.overdue? |
| 3246 | 3253 |
end |
| 3254 | ||
| 3255 |
def test_closable |
|
| 3256 |
issue10 = Issue.find(10) |
|
| 3257 |
assert issue10.closable? |
|
| 3258 |
assert_nil issue10.transition_warning |
|
| 3259 | ||
| 3260 |
# Issue blocked by another issue |
|
| 3261 |
issue9 = Issue.find(9) |
|
| 3262 |
assert !issue9.closable? |
|
| 3263 |
assert_equal l(:notice_issue_not_closable_by_blocking_issue), issue9.transition_warning |
|
| 3264 |
end |
|
| 3265 | ||
| 3266 |
def test_reopenable |
|
| 3267 |
parent = Issue.generate!(:status_id => 5) |
|
| 3268 |
child = parent.generate_child!(:status_id => 5) |
|
| 3269 | ||
| 3270 |
assert !child.reopenable? |
|
| 3271 |
assert_equal l(:notice_issue_not_reopenable_by_closed_parent_issue), child.transition_warning |
|
| 3272 |
end |
|
| 3247 | 3273 |
end |
- « Previous
- 1
- 2
- 3
- 4
- Next »