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 |