From 240f8be5cd68b13156752f7e9aa962999fa2673d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Codru=C8=9B=20Constantin=20Gu=C8=99oi?= Date: Mon, 27 Jun 2022 16:01:09 +0300 Subject: [PATCH 2/2] Fixes on top of issue ordering --- app/controllers/versions_controller.rb | 2 +- app/models/issue.rb | 6 ++--- app/models/issue_query.rb | 4 +-- .../20200315154300_add_issue_position.rb | 4 +-- lib/redmine/acts/positioned.rb | 26 +++++++++++++------ 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index 072c4ce6f..3401bf7ef 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -177,7 +177,7 @@ class VersionsController < ApplicationController def order_issues_by if Setting.manual_issue_position_in_versions == '1' - return "COALESCE(#{Issue.table_name}.position, 999999), #{Issue.table_name}.id" + return "COALESCE(#{Issue.table_name}.fixed_version_position, 999999), #{Issue.table_name}.id" else return "#{Tracker.table_name}.position, #{Issue.table_name}.id" end diff --git a/app/models/issue.rb b/app/models/issue.rb index 69af75172..5557cb2da 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -54,7 +54,7 @@ class Issue < ActiveRecord::Base acts_as_activity_provider :scope => proc {preload(:project, :author, :tracker, :status)}, :author_key => :author_id - acts_as_positioned :scope => [:fixed_version_id] + acts_as_positioned :scope => [:fixed_version_id], :column => :fixed_version_position DONE_RATIO_OPTIONS = %w(issue_field issue_status) @@ -513,7 +513,7 @@ class Issue < ActiveRecord::Base user.allowed_to?(:manage_subtasks, issue.project) end) safe_attributes( - 'position', + 'fixed_version_position', :if => lambda {|issue, user| user.allowed_to?(:change_issue_position_in_version, issue.project)} ) safe_attributes( @@ -867,7 +867,7 @@ class Issue < ActiveRecord::Base # Returns the names of attributes that are journalized when updating the issue def journalized_attribute_names - names = Issue.column_names - %w(id root_id lft rgt lock_version position created_on updated_on closed_on) + names = Issue.column_names - %w(id root_id lft rgt lock_version fixed_version_position created_on updated_on closed_on) if tracker names -= tracker.disabled_core_fields end diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 766276720..3cbc4475d 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -49,7 +49,7 @@ class IssueQuery < Query QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true), QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", :totalable => true), - QueryColumn.new(:position, :sortable => "#{Issue.table_name}.position"), + QueryColumn.new(:fixed_version_position, :sortable => "#{Issue.table_name}.fixed_version_position"), QueryColumn.new( :total_estimated_hours, :sortable => @@ -183,7 +183,7 @@ class IssueQuery < Query add_available_filter "start_date", :type => :date add_available_filter "due_date", :type => :date add_available_filter "estimated_hours", :type => :float - add_available_filter "position", :type => :integer + add_available_filter "fixed_version_position", :type => :integer if User.current.allowed_to?(:view_time_entries, project, :global => true) add_available_filter "spent_time", :type => :float, :label => :label_spent_time diff --git a/db/migrate/20200315154300_add_issue_position.rb b/db/migrate/20200315154300_add_issue_position.rb index ee0abec43..338e93ec6 100644 --- a/db/migrate/20200315154300_add_issue_position.rb +++ b/db/migrate/20200315154300_add_issue_position.rb @@ -1,9 +1,9 @@ class AddIssuePosition < ActiveRecord::Migration[5.2] def self.up - add_column :issues, :position, :integer + add_column :issues, :fixed_version_position, :integer end def self.down - remove_column :issues, :position + remove_column :issues, :fixed_version_position end end diff --git a/lib/redmine/acts/positioned.rb b/lib/redmine/acts/positioned.rb index ef25e48c7..da684d53f 100644 --- a/lib/redmine/acts/positioned.rb +++ b/lib/redmine/acts/positioned.rb @@ -34,7 +34,7 @@ module Redmine # or an array of symbols def acts_as_positioned(options = {}) class_attribute :positioned_options - self.positioned_options = {:scope => Array(options[:scope])} + self.positioned_options = {:scope => Array(options[:scope]), :column => options[:colunm] || :position } send :include, Redmine::Acts::Positioned::InstanceMethods @@ -70,8 +70,10 @@ module Redmine end def set_default_position - if position.nil? - self.position = position_scope.maximum(:position).to_i + (new_record? ? 1 : 0) + column = self.positioned_options[:column] + + if send(column).nil? + self.send(column + '=', position_scope.maximum(column).to_i + (new_record? ? 1 : 0)) end end @@ -89,14 +91,18 @@ module Redmine end def insert_position - position_scope.where("position >= ? AND id <> ?", position, id).update_all("position = position + 1") + column = self.positioned_options[:column] + + position_scope.where("#{column} >= ? AND id <> ?", position, id).update_all("#{column} = #{column} + 1") end def remove_position # this can be called in after_update or after_destroy callbacks # with different methods in Rails 5 for retrieving the previous value + column = self.positioned_options[:column] + previous = destroyed? ? position_was : position_before_last_save - position_scope_was.where("position >= ? AND id <> ?", previous, id).update_all("position = position - 1") + position_scope_was.where("#{column} >= ? AND id <> ?", previous, id).update_all("#{column} = #{column} - 1") end def position_scope_changed? @@ -104,17 +110,21 @@ module Redmine end def shift_positions + column = self.positioned_options[:column] + offset = position_before_last_save <=> position min, max = [position, position_before_last_save].sort - r = position_scope.where("id <> ? AND position BETWEEN ? AND ?", id, min, max).update_all("position = position + #{offset}") + r = position_scope.where("id <> ? AND #{column} BETWEEN ? AND ?", id, min, max).update_all("#{column} = #{column} + #{offset}") if r != max - min reset_positions_in_list end end def reset_positions_in_list - position_scope.reorder(:position, :id).pluck(:id).each_with_index do |record_id, p| - self.class.where(:id => record_id).update_all(:position => p+1) + column = self.positioned_options[:column] + + position_scope.reorder(column, :id).pluck(:id).each_with_index do |record_id, p| + self.class.where(:id => record_id).update_all(column => p+1) end end end -- 2.36.1