Feature #2568 ยป 2568-add-description-to-issue-statuses.patch
app/models/issue_status.rb | ||
---|---|---|
31 | 31 |
validates_presence_of :name |
32 | 32 |
validates_uniqueness_of :name, :case_sensitive => true |
33 | 33 |
validates_length_of :name, :maximum => 30 |
34 |
validates_length_of :description, :maximum => 255 |
|
34 | 35 |
validates_inclusion_of :default_done_ratio, :in => 0..100, :allow_nil => true |
35 | 36 | |
36 | 37 |
scope :sorted, lambda {order(:position)} |
... | ... | |
38 | 39 | |
39 | 40 |
safe_attributes( |
40 | 41 |
'name', |
42 |
'description', |
|
41 | 43 |
'is_closed', |
42 | 44 |
'position', |
43 | 45 |
'default_done_ratio') |
app/views/issue_statuses/_form.html.erb | ||
---|---|---|
2 | 2 | |
3 | 3 |
<div class="box tabular"> |
4 | 4 |
<p><%= f.text_field :name, :required => true %></p> |
5 |
<p><%= f.text_area :description, :rows => 4 %></p> |
|
5 | 6 |
<% if Issue.use_status_for_done_ratio? %> |
6 | 7 |
<p><%= f.select :default_done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :include_blank => true, :label => :field_done_ratio %></p> |
7 | 8 |
<% end %> |
app/views/issue_statuses/index.api.rsb | ||
---|---|---|
4 | 4 |
api.id status.id |
5 | 5 |
api.name status.name |
6 | 6 |
api.is_closed status.is_closed |
7 |
api.description status.description |
|
7 | 8 |
end |
8 | 9 |
end |
9 | 10 |
end |
app/views/issue_statuses/index.html.erb | ||
---|---|---|
12 | 12 |
<th><%=l(:field_done_ratio)%></th> |
13 | 13 |
<% end %> |
14 | 14 |
<th><%=l(:field_is_closed)%></th> |
15 |
<th><%=l(:field_description)%></th> |
|
15 | 16 |
<th></th> |
16 | 17 |
<th></th> |
17 | 18 |
</tr></thead> |
... | ... | |
23 | 24 |
<td><%= status.default_done_ratio %></td> |
24 | 25 |
<% end %> |
25 | 26 |
<td><%= checked_image status.is_closed? %></td> |
27 |
<td class="description"><%= status.description %></td> |
|
26 | 28 |
<td> |
27 | 29 |
<% unless WorkflowTransition.where('old_status_id = ? OR new_status_id = ?', status.id, status.id).exists? %> |
28 | 30 |
<span class="icon icon-warning"> |
app/views/issues/_attributes.html.erb | ||
---|---|---|
5 | 5 |
<% if @issue.safe_attribute?('status_id') && @allowed_statuses.present? %> |
6 | 6 |
<p> |
7 | 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)" %> |
|
8 |
:onchange => "updateIssueFrom('#{escape_javascript(update_issue_form_path(@project, @issue))}', this)", |
|
9 |
:title => @issue.status.description %> |
|
10 |
<%= content_tag 'a', l(:label_open_issue_status_description), :class => 'icon-only icon-help', :title => l(:label_open_issue_status_description), :onclick => "showModal('issue_statuses_description', '500px'); return false;", :href => '#' if @allowed_statuses.any? {|s| s.description.present? } %> |
|
9 | 11 |
<% if @issue.transition_warning %> |
10 | 12 |
<span class="icon-only icon-warning" title="<%= @issue.transition_warning %>"><%= @issue.transition_warning %></span> |
11 | 13 |
<% end %> |
12 | 14 |
</p> |
15 |
<%= render partial: 'issues/issue_status_description', locals: { issue_statuses: @allowed_statuses } %> |
|
13 | 16 |
<%= hidden_field_tag 'was_default_status', @issue.status_id, :id => nil if @issue.status == @issue.default_status %> |
14 | 17 |
<% else %> |
15 | 18 |
<p><label><%= l(:field_status) %></label> <%= @issue.status %></p> |
app/views/issues/_issue_status_description.html.erb | ||
---|---|---|
1 |
<% if issue_statuses.any? {|s| s.description.present? } %> |
|
2 |
<div class="modal" id="issue_statuses_description"> |
|
3 |
<h3 class="title"><%= l(:label_issue_statuses_description) %></h3> |
|
4 |
<dl> |
|
5 |
<% issue_statuses.each do |issue_status| %> |
|
6 |
<% if issue_status.description.present? %> |
|
7 |
<dt><%= content_tag 'a', issue_status.name, :onclick => "selectIssueStatus('#{issue_status.id}'); return false;", :href => '#', :title => l(:text_select_apply_issue_status) %></dt> |
|
8 |
<dd><%= issue_status.description %></dd> |
|
9 |
<% end %> |
|
10 |
<% end %> |
|
11 |
</dl> |
|
12 |
</div> |
|
13 |
<% end %> |
|
14 |
<%= javascript_tag do %> |
|
15 |
function selectIssueStatus(id) { |
|
16 |
var target = $('#issue_status_id'); |
|
17 |
target.attr("selected", false); |
|
18 |
target.find('option[value="' + id + '"]').prop('selected', true); |
|
19 |
target.trigger('change'); |
|
20 |
hideModal('#issue_statuses_description h3'); |
|
21 |
} |
|
22 |
<% end %> |
config/locales/en.yml | ||
---|---|---|
1119 | 1119 |
label_inherited_from_group: "Inherited from group %{name}" |
1120 | 1120 |
label_trackers_description: Trackers description |
1121 | 1121 |
label_open_trackers_description: View all trackers description |
1122 |
label_issue_statuses_description: Issue Status description |
|
1123 |
label_open_issue_status_description: View all issue statuses description |
|
1122 | 1124 |
label_preferred_body_part_text: Text |
1123 | 1125 |
label_preferred_body_part_html: HTML |
1124 | 1126 |
label_issue_history_properties: Property changes |
... | ... | |
1314 | 1316 |
text_project_closed: This project is closed and read-only. |
1315 | 1317 |
text_turning_multiple_off: "If you disable multiple values, multiple values will be removed in order to preserve only one value per item." |
1316 | 1318 |
text_select_apply_tracker: "Select tracker" |
1319 |
text_select_apply_issue_status: "Select issue status" |
|
1317 | 1320 |
text_avatar_server_config_html: The current avatar server is <a href="%{url}">%{url}</a>. You can configure it in config/configuration.yml. |
1318 | 1321 |
text_no_subject: no subject |
1319 | 1322 |
text_allowed_queries_to_select: Public (to any users) queries only selectable |
db/migrate/20230818020734_add_status_description.rb | ||
---|---|---|
1 |
class AddStatusDescription < ActiveRecord::Migration[6.1] |
|
2 |
def up |
|
3 |
add_column :issue_statuses, :description, :string, :after => :name |
|
4 |
end |
|
5 | ||
6 |
def down |
|
7 |
remove_column :issue_statuses, :description |
|
8 |
end |
|
9 |
end |
public/stylesheets/application.css | ||
---|---|---|
578 | 578 |
#issue_tree .issue > td.assigned_to, #relations .issue > td.assigned_to { |
579 | 579 |
white-space: nowrap; |
580 | 580 |
} |
581 |
#trackers_description {display:none;} |
|
582 |
#trackers_description dt {font-weight: bold; text-decoration: underline;} |
|
583 |
#trackers_description dd {margin: 0; padding: 0 0 1em 0;} |
|
581 |
#trackers_description, #issue_statuses_description {display:none;}
|
|
582 |
#trackers_description dt, #issue_statuses_description dt {font-weight: bold; text-decoration: underline;}
|
|
583 |
#trackers_description dd, #issue_statuses_description dd {margin: 0; padding: 0 0 1em 0;}
|
|
584 | 584 | |
585 | 585 |
#issue-form .assign-to-me-link { padding-left: 5px; } |
586 | 586 |
test/fixtures/issue_statuses.yml | ||
---|---|---|
2 | 2 |
issue_statuses_001: |
3 | 3 |
id: 1 |
4 | 4 |
name: New |
5 |
description: Description for New issue status |
|
5 | 6 |
is_closed: false |
6 | 7 |
position: 1 |
7 | 8 |
issue_statuses_002: |
8 | 9 |
id: 2 |
9 | 10 |
name: Assigned |
11 |
description: Description for Assigned issue status |
|
10 | 12 |
is_closed: false |
11 | 13 |
position: 2 |
12 | 14 |
issue_statuses_003: |
13 | 15 |
id: 3 |
14 | 16 |
name: Resolved |
17 |
description: Description for Resolved issue status |
|
15 | 18 |
is_closed: false |
16 | 19 |
position: 3 |
17 | 20 |
issue_statuses_004: |
18 |
name: Feedback |
|
19 | 21 |
id: 4 |
22 |
name: Feedback |
|
20 | 23 |
is_closed: false |
21 | 24 |
position: 4 |
22 | 25 |
issue_statuses_005: |
test/functional/issue_statuses_controller_test.rb | ||
---|---|---|
64 | 64 |
get :new |
65 | 65 |
assert_response :success |
66 | 66 |
assert_select 'input[name=?]', 'issue_status[name]' |
67 |
assert_select 'textarea[name=?]', 'issue_status[description]' |
|
67 | 68 |
end |
68 | 69 | |
69 | 70 |
def test_create |
... | ... | |
72 | 73 |
:create, |
73 | 74 |
:params => { |
74 | 75 |
:issue_status => { |
75 |
:name => 'New status' |
|
76 |
:name => 'New status', |
|
77 |
:description => 'New status description' |
|
76 | 78 |
} |
77 | 79 |
} |
78 | 80 |
) |
... | ... | |
80 | 82 |
assert_redirected_to :action => 'index' |
81 | 83 |
status = IssueStatus.order('id DESC').first |
82 | 84 |
assert_equal 'New status', status.name |
85 |
assert_equal 'New status description', status.description |
|
83 | 86 |
end |
84 | 87 | |
85 | 88 |
def test_create_with_failure |
... | ... | |
99 | 102 |
get(:edit, :params => {:id => '3'}) |
100 | 103 |
assert_response :success |
101 | 104 |
assert_select 'input[name=?][value=?]', 'issue_status[name]', 'Resolved' |
105 |
assert_select 'textarea[name=?]', 'issue_status[description]', 'Description for Resolved issue status' |
|
102 | 106 |
end |
103 | 107 | |
104 | 108 |
def test_update |
... | ... | |
107 | 111 |
:params => { |
108 | 112 |
:id => '3', |
109 | 113 |
:issue_status => { |
110 |
:name => 'Renamed status' |
|
114 |
:name => 'Renamed status', |
|
115 |
:description => 'Renamed status description' |
|
111 | 116 |
} |
112 | 117 |
} |
113 | 118 |
) |
114 | 119 |
assert_redirected_to :action => 'index' |
115 | 120 |
status = IssueStatus.find(3) |
116 | 121 |
assert_equal 'Renamed status', status.name |
122 |
assert_equal 'Renamed status description', status.description |
|
117 | 123 |
end |
118 | 124 | |
119 | 125 |
def test_update_with_failure |
test/functional/issues_controller_test.rb | ||
---|---|---|
3881 | 3881 |
assert_select 'div#trackers_description', 0 |
3882 | 3882 |
end |
3883 | 3883 | |
3884 |
def test_get_new_should_show_issue_status_description |
|
3885 |
@request.session[:user_id] = 2 |
|
3886 |
get :new, :params => { |
|
3887 |
:project_id => 1, |
|
3888 |
:issue => { |
|
3889 |
:status_id => 2 |
|
3890 |
} |
|
3891 |
} |
|
3892 |
assert_response :success |
|
3893 | ||
3894 |
assert_select 'form#issue-form' do |
|
3895 |
assert_select 'a[title=?]', 'View all issue statuses description', :text => 'View all issue statuses description' |
|
3896 |
assert_select 'select[name=?][title=?]', 'issue[status_id]', 'Description for Assigned issue status' |
|
3897 |
end |
|
3898 | ||
3899 |
assert_select 'div#issue_statuses_description' do |
|
3900 |
assert_select 'h3', :text => 'Issue Status description', :count => 1 |
|
3901 |
assert_select 'dt', 2 |
|
3902 |
assert_select 'dt', :text => 'New', :count => 1 |
|
3903 |
assert_select 'dd', :text => 'Description for New issue status', :count => 1 |
|
3904 |
end |
|
3905 |
end |
|
3906 | ||
3907 |
def test_get_new_should_not_show_issue_status_description |
|
3908 |
IssueStatus.update_all(:description => '') |
|
3909 | ||
3910 |
@request.session[:user_id] = 2 |
|
3911 |
get :new, :params => { |
|
3912 |
:project_id => 1, |
|
3913 |
:issue => { |
|
3914 |
:status_id => 2 |
|
3915 |
} |
|
3916 |
} |
|
3917 |
assert_response :success |
|
3918 | ||
3919 |
assert_select 'form#issue-form' do |
|
3920 |
assert_select 'a[title=?]', 'View all issue statuses description', 0 |
|
3921 |
assert_select 'select[name=?][title=?]', 'issue[status_id]', '' |
|
3922 |
end |
|
3923 | ||
3924 |
assert_select 'div#issue_statuses_description', 0 |
|
3925 |
end |
|
3926 | ||
3884 | 3927 |
def test_get_new_should_show_create_and_follow_button_when_issue_is_subtask_and_back_url_is_present |
3885 | 3928 |
@request.session[:user_id] = 2 |
3886 | 3929 |
get :new, params: { |
test/integration/api_test/issue_statuses_test.rb | ||
---|---|---|
29 | 29 |
assert_equal 'application/xml', @response.media_type |
30 | 30 |
assert_select 'issue_statuses[type=array] issue_status id', :text => '2' do |
31 | 31 |
assert_select '~ name', :text => 'Assigned' |
32 |
assert_select '~ is_closed', :text => 'false' |
|
33 |
assert_select '~ description', :text => 'Description for Assigned issue status' |
|
32 | 34 |
end |
33 | 35 |
end |
34 | 36 |
end |
test/unit/issue_status_test.rb | ||
---|---|---|
151 | 151 |
assert !issue.closed? |
152 | 152 |
assert_nil issue.closed_on |
153 | 153 |
end |
154 | ||
155 |
def test_issue_status_should_have_description |
|
156 |
issue_status = IssueStatus.find(1) |
|
157 |
assert issue_status.respond_to?(:description) |
|
158 |
assert_equal 'Description for New issue status', issue_status.description |
|
159 |
end |
|
154 | 160 |
end |