Project

General

Profile

Patch #34426 » issue_categories_sortable.diff

Karel Pičman, 2021-02-08 14:59

View differences:

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.order(:name).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
(2-2/2)