mirror of
https://github.com/redmine/redmine.git
synced 2025-11-09 06:46:01 +01:00
Add description for issue statuses and display them in issue new/edit form (#2568).
Patch by Takenori TAKAKI. git-svn-id: https://svn.redmine.org/redmine/trunk@22288 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -31,6 +31,7 @@ class IssueStatus < ActiveRecord::Base
|
|||||||
validates_presence_of :name
|
validates_presence_of :name
|
||||||
validates_uniqueness_of :name, :case_sensitive => true
|
validates_uniqueness_of :name, :case_sensitive => true
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
|
validates_length_of :description, :maximum => 255
|
||||||
validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
|
validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true
|
||||||
|
|
||||||
scope :sorted, lambda {order(:position)}
|
scope :sorted, lambda {order(:position)}
|
||||||
@@ -38,6 +39,7 @@ class IssueStatus < ActiveRecord::Base
|
|||||||
|
|
||||||
safe_attributes(
|
safe_attributes(
|
||||||
'name',
|
'name',
|
||||||
|
'description',
|
||||||
'is_closed',
|
'is_closed',
|
||||||
'position',
|
'position',
|
||||||
'default_done_ratio')
|
'default_done_ratio')
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<div class="box tabular">
|
<div class="box tabular">
|
||||||
<p><%= f.text_field :name, :required => true %></p>
|
<p><%= f.text_field :name, :required => true %></p>
|
||||||
|
<p><%= f.text_area :description, :rows => 4 %></p>
|
||||||
<% if Issue.use_status_for_done_ratio? %>
|
<% if Issue.use_status_for_done_ratio? %>
|
||||||
<p><%= f.select :default_done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :include_blank => true, :label => :field_done_ratio %></p>
|
<p><%= f.select :default_done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :include_blank => true, :label => :field_done_ratio %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ api.array :issue_statuses do
|
|||||||
api.id status.id
|
api.id status.id
|
||||||
api.name status.name
|
api.name status.name
|
||||||
api.is_closed status.is_closed
|
api.is_closed status.is_closed
|
||||||
|
api.description status.description
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<th><%=l(:field_done_ratio)%></th>
|
<th><%=l(:field_done_ratio)%></th>
|
||||||
<% end %>
|
<% end %>
|
||||||
<th><%=l(:field_is_closed)%></th>
|
<th><%=l(:field_is_closed)%></th>
|
||||||
|
<th><%=l(:field_description)%></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
<td><%= status.default_done_ratio %></td>
|
<td><%= status.default_done_ratio %></td>
|
||||||
<% end %>
|
<% end %>
|
||||||
<td><%= checked_image status.is_closed? %></td>
|
<td><%= checked_image status.is_closed? %></td>
|
||||||
|
<td class="description"><%= status.description %></td>
|
||||||
<td>
|
<td>
|
||||||
<% unless WorkflowTransition.where('old_status_id = ? OR new_status_id = ?', status.id, status.id).exists? %>
|
<% unless WorkflowTransition.where('old_status_id = ? OR new_status_id = ?', status.id, status.id).exists? %>
|
||||||
<span class="icon icon-warning">
|
<span class="icon icon-warning">
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %>
|
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %>
|
||||||
<p>
|
<p>
|
||||||
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
|
<%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), {:required => true},
|
||||||
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)" %>
|
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)",
|
||||||
|
:title => @issue.status.description %>
|
||||||
|
<%= content_tag 'a', l(:label_open_issue_statuses_description), :class => 'icon-only icon-help', :title => l(:label_open_issue_statuses_description), :onclick => "showModal('issue_statuses_description', '500px'); return false;", :href => '#' if @allowed_statuses.any? {|s| s.description.present? } %>
|
||||||
<% if @issue.transition_warning %>
|
<% if @issue.transition_warning %>
|
||||||
<span class="icon-only icon-warning" title="<%= @issue.transition_warning %>"><%= @issue.transition_warning %></span>
|
<span class="icon-only icon-warning" title="<%= @issue.transition_warning %>"><%= @issue.transition_warning %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
|
<%= render partial: 'issues/issue_status_description', locals: { issue_statuses: @allowed_statuses } %>
|
||||||
<%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %>
|
<%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<p><label><%= l(:field_status) %></label> <%= @issue.status %></p>
|
<p><label><%= l(:field_status) %></label> <%= @issue.status %></p>
|
||||||
|
|||||||
@@ -1119,6 +1119,8 @@ en:
|
|||||||
label_inherited_from_group: "Inherited from group %{name}"
|
label_inherited_from_group: "Inherited from group %{name}"
|
||||||
label_trackers_description: Trackers description
|
label_trackers_description: Trackers description
|
||||||
label_open_trackers_description: View all trackers description
|
label_open_trackers_description: View all trackers description
|
||||||
|
label_issue_statuses_description: Issue statuses description
|
||||||
|
label_open_issue_statuses_description: View all issue statuses description
|
||||||
label_preferred_body_part_text: Text
|
label_preferred_body_part_text: Text
|
||||||
label_preferred_body_part_html: HTML
|
label_preferred_body_part_html: HTML
|
||||||
label_issue_history_properties: Property changes
|
label_issue_history_properties: Property changes
|
||||||
@@ -1314,6 +1316,7 @@ en:
|
|||||||
text_project_closed: This project is closed and read-only.
|
text_project_closed: This project is closed and read-only.
|
||||||
text_turning_multiple_off: "If you disable multiple values, multiple values will be removed in order to preserve only one value per item."
|
text_turning_multiple_off: "If you disable multiple values, multiple values will be removed in order to preserve only one value per item."
|
||||||
text_select_apply_tracker: "Select tracker"
|
text_select_apply_tracker: "Select tracker"
|
||||||
|
text_select_apply_issue_status: "Select issue status"
|
||||||
text_avatar_server_config_html: The current avatar server is <a href="%{url}">%{url}</a>. You can configure it in config/configuration.yml.
|
text_avatar_server_config_html: The current avatar server is <a href="%{url}">%{url}</a>. You can configure it in config/configuration.yml.
|
||||||
text_no_subject: no subject
|
text_no_subject: no subject
|
||||||
text_allowed_queries_to_select: Public (to any users) queries only selectable
|
text_allowed_queries_to_select: Public (to any users) queries only selectable
|
||||||
|
|||||||
@@ -578,9 +578,9 @@ body.controller-issues h2.inline-flex {padding-right: 0}
|
|||||||
#issue_tree .issue > td.assigned_to, #relations .issue > td.assigned_to {
|
#issue_tree .issue > td.assigned_to, #relations .issue > td.assigned_to {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
#trackers_description {display:none;}
|
#trackers_description, #issue_statuses_description {display:none;}
|
||||||
#trackers_description dt {font-weight: bold; text-decoration: underline;}
|
#trackers_description dt, #issue_statuses_description dt {font-weight: bold; text-decoration: underline;}
|
||||||
#trackers_description dd {margin: 0; padding: 0 0 1em 0;}
|
#trackers_description dd, #issue_statuses_description dd {margin: 0; padding: 0 0 1em 0;}
|
||||||
|
|
||||||
#issue-form .assign-to-me-link { padding-left: 5px; }
|
#issue-form .assign-to-me-link { padding-left: 5px; }
|
||||||
|
|
||||||
|
|||||||
5
test/fixtures/issue_statuses.yml
vendored
5
test/fixtures/issue_statuses.yml
vendored
@@ -2,21 +2,24 @@
|
|||||||
issue_statuses_001:
|
issue_statuses_001:
|
||||||
id: 1
|
id: 1
|
||||||
name: New
|
name: New
|
||||||
|
description: Description for New issue status
|
||||||
is_closed: false
|
is_closed: false
|
||||||
position: 1
|
position: 1
|
||||||
issue_statuses_002:
|
issue_statuses_002:
|
||||||
id: 2
|
id: 2
|
||||||
name: Assigned
|
name: Assigned
|
||||||
|
description: Description for Assigned issue status
|
||||||
is_closed: false
|
is_closed: false
|
||||||
position: 2
|
position: 2
|
||||||
issue_statuses_003:
|
issue_statuses_003:
|
||||||
id: 3
|
id: 3
|
||||||
name: Resolved
|
name: Resolved
|
||||||
|
description: Description for Resolved issue status
|
||||||
is_closed: false
|
is_closed: false
|
||||||
position: 3
|
position: 3
|
||||||
issue_statuses_004:
|
issue_statuses_004:
|
||||||
name: Feedback
|
|
||||||
id: 4
|
id: 4
|
||||||
|
name: Feedback
|
||||||
is_closed: false
|
is_closed: false
|
||||||
position: 4
|
position: 4
|
||||||
issue_statuses_005:
|
issue_statuses_005:
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ class IssueStatusesControllerTest < Redmine::ControllerTest
|
|||||||
get :new
|
get :new
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select 'input[name=?]', 'issue_status[name]'
|
assert_select 'input[name=?]', 'issue_status[name]'
|
||||||
|
assert_select 'textarea[name=?]', 'issue_status[description]'
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create
|
def test_create
|
||||||
@@ -72,7 +73,8 @@ class IssueStatusesControllerTest < Redmine::ControllerTest
|
|||||||
:create,
|
:create,
|
||||||
:params => {
|
:params => {
|
||||||
:issue_status => {
|
:issue_status => {
|
||||||
:name => 'New status'
|
:name => 'New status',
|
||||||
|
:description => 'New status description'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -80,6 +82,7 @@ class IssueStatusesControllerTest < Redmine::ControllerTest
|
|||||||
assert_redirected_to :action => 'index'
|
assert_redirected_to :action => 'index'
|
||||||
status = IssueStatus.order('id DESC').first
|
status = IssueStatus.order('id DESC').first
|
||||||
assert_equal 'New status', status.name
|
assert_equal 'New status', status.name
|
||||||
|
assert_equal 'New status description', status.description
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create_with_failure
|
def test_create_with_failure
|
||||||
@@ -99,6 +102,7 @@ class IssueStatusesControllerTest < Redmine::ControllerTest
|
|||||||
get(:edit, :params => {:id => '3'})
|
get(:edit, :params => {:id => '3'})
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select 'input[name=?][value=?]', 'issue_status[name]', 'Resolved'
|
assert_select 'input[name=?][value=?]', 'issue_status[name]', 'Resolved'
|
||||||
|
assert_select 'textarea[name=?]', 'issue_status[description]', 'Description for Resolved issue status'
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_update
|
def test_update
|
||||||
@@ -107,13 +111,15 @@ class IssueStatusesControllerTest < Redmine::ControllerTest
|
|||||||
:params => {
|
:params => {
|
||||||
:id => '3',
|
:id => '3',
|
||||||
:issue_status => {
|
:issue_status => {
|
||||||
:name => 'Renamed status'
|
:name => 'Renamed status',
|
||||||
|
:description => 'Renamed status description'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
assert_redirected_to :action => 'index'
|
assert_redirected_to :action => 'index'
|
||||||
status = IssueStatus.find(3)
|
status = IssueStatus.find(3)
|
||||||
assert_equal 'Renamed status', status.name
|
assert_equal 'Renamed status', status.name
|
||||||
|
assert_equal 'Renamed status description', status.description
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_update_with_failure
|
def test_update_with_failure
|
||||||
|
|||||||
@@ -3881,6 +3881,49 @@ class IssuesControllerTest < Redmine::ControllerTest
|
|||||||
assert_select 'div#trackers_description', 0
|
assert_select 'div#trackers_description', 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_get_new_should_show_issue_status_description
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
get :new, :params => {
|
||||||
|
:project_id => 1,
|
||||||
|
:issue => {
|
||||||
|
:status_id => 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
assert_select 'form#issue-form' do
|
||||||
|
assert_select 'a[title=?]', 'View all issue statuses description', :text => 'View all issue statuses description'
|
||||||
|
assert_select 'select[name=?][title=?]', 'issue[status_id]', 'Description for Assigned issue status'
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_select 'div#issue_statuses_description' do
|
||||||
|
assert_select 'h3', :text => 'Issue statuses description', :count => 1
|
||||||
|
assert_select 'dt', 2
|
||||||
|
assert_select 'dt', :text => 'New', :count => 1
|
||||||
|
assert_select 'dd', :text => 'Description for New issue status', :count => 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_get_new_should_not_show_issue_status_description
|
||||||
|
IssueStatus.update_all(:description => '')
|
||||||
|
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
get :new, :params => {
|
||||||
|
:project_id => 1,
|
||||||
|
:issue => {
|
||||||
|
:status_id => 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
assert_select 'form#issue-form' do
|
||||||
|
assert_select 'a[title=?]', 'View all issue statuses description', 0
|
||||||
|
assert_select 'select[name=?][title=?]', 'issue[status_id]', ''
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_select 'div#issue_statuses_description', 0
|
||||||
|
end
|
||||||
|
|
||||||
def test_get_new_should_show_create_and_follow_button_when_issue_is_subtask_and_back_url_is_present
|
def test_get_new_should_show_create_and_follow_button_when_issue_is_subtask_and_back_url_is_present
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
get :new, params: {
|
get :new, params: {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ class Redmine::ApiTest::IssueStatusesTest < Redmine::ApiTest::Base
|
|||||||
assert_equal 'application/xml', @response.media_type
|
assert_equal 'application/xml', @response.media_type
|
||||||
assert_select 'issue_statuses[type=array] issue_status id', :text => '2' do
|
assert_select 'issue_statuses[type=array] issue_status id', :text => '2' do
|
||||||
assert_select '~ name', :text => 'Assigned'
|
assert_select '~ name', :text => 'Assigned'
|
||||||
|
assert_select '~ is_closed', :text => 'false'
|
||||||
|
assert_select '~ description', :text => 'Description for Assigned issue status'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -151,4 +151,9 @@ class IssueStatusTest < ActiveSupport::TestCase
|
|||||||
assert !issue.closed?
|
assert !issue.closed?
|
||||||
assert_nil issue.closed_on
|
assert_nil issue.closed_on
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_issue_status_should_have_description
|
||||||
|
issue_status = IssueStatus.find(1)
|
||||||
|
assert_equal 'Description for New issue status', issue_status.description
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user