Patch #34426 » issue_categories_sortable.diff
app/controllers/issue_categories_controller.rb (working copy) | ||
---|---|---|
29 | 29 |
def index |
30 | 30 |
respond_to do |format| |
31 | 31 |
format.html {redirect_to_settings_in_projects} |
32 |
format.api {@categories = @project.issue_categories.to_a} |
|
32 |
format.api {@categories = @project.issue_categories.sorted.to_a}
|
|
33 | 33 |
end |
34 | 34 |
end |
35 | 35 | |
... | ... | |
85 | 85 |
flash[:notice] = l(:notice_successful_update) |
86 | 86 |
redirect_to_settings_in_projects |
87 | 87 |
end |
88 |
format.js {head 200} |
|
88 | 89 |
format.api {render_api_ok} |
89 | 90 |
end |
90 | 91 |
else |
91 | 92 |
respond_to do |format| |
92 | 93 |
format.html {render :action => 'edit'} |
93 | 94 |
format.api {render_validation_errors(@category)} |
95 |
format.js {head 422} |
|
94 | 96 |
end |
95 | 97 |
end |
96 | 98 |
end |
app/models/issue_category.rb (working copy) | ||
---|---|---|
22 | 22 |
belongs_to :project |
23 | 23 |
belongs_to :assigned_to, :class_name => 'Principal' |
24 | 24 |
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify |
25 |
acts_as_positioned |
|
25 | 26 | |
26 | 27 |
validates_presence_of :name |
27 | 28 |
validates_uniqueness_of :name, :scope => [:project_id] |
28 | 29 |
validates_length_of :name, :maximum => 60 |
29 | 30 | |
30 |
safe_attributes 'name', 'assigned_to_id' |
|
31 |
safe_attributes 'name', 'assigned_to_id', 'position'
|
|
31 | 32 | |
33 |
scope :sorted, lambda {order(:position)} |
|
32 | 34 |
scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} |
33 | 35 | |
34 | 36 |
alias :destroy_without_reassign :destroy |
... | ... | |
43 | 45 |
end |
44 | 46 | |
45 | 47 |
def <=>(category) |
46 |
name <=> category.name
|
|
48 |
position <=> category.position
|
|
47 | 49 |
end |
48 | 50 | |
49 | 51 |
def to_s; name end |
app/models/project.rb (working copy) | ||
---|---|---|
46 | 46 |
has_many :queries, :dependent => :delete_all |
47 | 47 |
has_many :documents, :dependent => :destroy |
48 | 48 |
has_many :news, lambda {includes(:author)}, :dependent => :destroy |
49 |
has_many :issue_categories, lambda {order(:name)}, :dependent => :delete_all
|
|
49 |
has_many :issue_categories, lambda {order(:position)}, :dependent => :delete_all
|
|
50 | 50 |
has_many :boards, lambda {order(:position)}, :inverse_of => :project, :dependent => :destroy |
51 | 51 |
has_one :repository, lambda {where(:is_default => true)} |
52 | 52 |
has_many :repositories, :dependent => :destroy |
app/views/projects/settings/_issue_categories.html.erb (working copy) | ||
---|---|---|
1 | 1 |
<p><%= link_to l(:label_issue_category_new), new_project_issue_category_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_categories, @project) %></p> |
2 | 2 | |
3 | 3 |
<% if @project.issue_categories.any? %> |
4 |
<table class="list"> |
|
4 |
<table class="list issue_categories">
|
|
5 | 5 |
<thead><tr> |
6 | 6 |
<th><%= l(:label_issue_category) %></th> |
7 | 7 |
<th><%= l(:field_assigned_to) %></th> |
... | ... | |
15 | 15 |
<td><%= category.assigned_to.name if category.assigned_to %></td> |
16 | 16 |
<td class="buttons"> |
17 | 17 |
<% if User.current.allowed_to?(:manage_categories, @project) %> |
18 |
<%= reorder_handle category %> |
|
18 | 19 |
<%= link_to l(:button_edit), edit_issue_category_path(category), :class => 'icon icon-edit' %> |
19 | 20 |
<%= delete_link issue_category_path(category) %> |
20 | 21 |
<% end %> |
... | ... | |
27 | 28 |
<% else %> |
28 | 29 |
<p class="nodata"><%= l(:label_no_data) %></p> |
29 | 30 |
<% end %> |
31 | ||
32 |
<%= javascript_tag do %> |
|
33 |
$(function() { $("table.issue_categories tbody").positionedItems(); }); |
|
34 |
<% end %> |
config/routes.rb (working copy) | ||
---|---|---|
127 | 127 |
end |
128 | 128 | |
129 | 129 |
member do |
130 |
get 'settings(/:tab)', :action => 'settings', :as => 'settings'
|
|
130 |
match 'settings(/:tab)', action: 'settings', as: 'settings', via: [:get, :put]
|
|
131 | 131 |
post 'archive' |
132 | 132 |
post 'unarchive' |
133 | 133 |
post 'close' |
db/migrate/20201209122301_add_issue_category_position.rb (working copy) | ||
---|---|---|
1 |
class AddIssueCategoryPosition < ActiveRecord::Migration[5.2] |
|
2 |
def self.up |
|
3 |
add_column :issue_categories, :position, :integer, default: 1 |
|
4 |
IssueCategory.all.each_with_index { |category, i| category.update_attribute(:position, i + 1) } |
|
5 |
end |
|
6 | ||
7 |
def self.down |
|
8 |
remove_column :issue_categories, :position |
|
9 |
end |
|
10 |
end |
test/fixtures/issue_categories.yml (working copy) | ||
---|---|---|
3 | 3 |
name: Printing |
4 | 4 |
project_id: 1 |
5 | 5 |
assigned_to_id: 2 |
6 |
position: 1 |
|
6 | 7 |
id: 1 |
7 | 8 |
issue_categories_002: |
8 | 9 |
name: Recipes |
9 | 10 |
project_id: 1 |
10 |
assigned_to_id: |
|
11 |
assigned_to_id: |
|
12 |
position: 2 |
|
11 | 13 |
id: 2 |
12 | 14 |
issue_categories_003: |
13 | 15 |
name: Stock management |
14 | 16 |
project_id: 2 |
15 |
assigned_to_id: |
|
17 |
assigned_to_id: |
|
18 |
position: 3 |
|
16 | 19 |
id: 3 |
17 | 20 |
issue_categories_004: |
18 | 21 |
name: Printing |
19 | 22 |
project_id: 2 |
20 |
assigned_to_id: |
|
23 |
assigned_to_id: |
|
24 |
position: 4 |
|
21 | 25 |
id: 4 |
test/functional/issue_categories_controller_test.rb (working copy) | ||
---|---|---|
137 | 137 |
:params => { |
138 | 138 |
:id => 2, |
139 | 139 |
:issue_category => { |
140 |
:name => 'Testing' |
|
140 |
:name => 'Testing', |
|
141 |
:position => 3 |
|
141 | 142 |
} |
142 | 143 |
} |
143 | 144 |
) |
144 | 145 |
end |
145 | 146 |
assert_redirected_to '/projects/ecookbook/settings/categories' |
146 |
assert_equal 'Testing', IssueCategory.find(2).name |
|
147 |
issue_category = IssueCategory.find(2) |
|
148 |
assert_equal 'Testing', issue_category.name |
|
149 |
assert_equal 3, issue_category.position |
|
147 | 150 |
end |
148 | 151 | |
149 | 152 |
def test_update_failure |
test/unit/issue_category_test.rb (working copy) | ||
---|---|---|
31 | 31 |
assert IssueCategory.new(:project_id => 2, :name => 'New category').save |
32 | 32 |
category = IssueCategory.order('id DESC').first |
33 | 33 |
assert_equal 'New category', category.name |
34 |
assert_equal 1, category.position |
|
34 | 35 |
end |
35 | 36 | |
36 | 37 |
def test_create_with_group_assignment |