You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sort_criteria.rb 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2022 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. module Redmine
  19. class SortCriteria < Array
  20. def initialize(arg=nil)
  21. super()
  22. if arg.is_a?(Array)
  23. replace arg
  24. elsif arg.is_a?(String)
  25. replace arg.split(',').collect {|s| s.split(':')[0..1]}
  26. elsif arg.respond_to?(:values)
  27. replace arg.values
  28. elsif arg
  29. raise ArgumentError.new("SortCriteria#new takes an Array, String or Hash, not a #{arg.class.name}.")
  30. end
  31. normalize!
  32. end
  33. def to_param
  34. self.collect {|k,o| k + (o == 'desc' ? ':desc' : '')}.join(',')
  35. end
  36. def to_a
  37. Array.new(self)
  38. end
  39. def add!(key, asc)
  40. key = key.to_s
  41. delete_if {|k,o| k == key}
  42. prepend([key, asc])
  43. normalize!
  44. end
  45. def add(*args)
  46. self.class.new(self).add!(*args)
  47. end
  48. def first_key
  49. first.try(:first)
  50. end
  51. def first_asc?
  52. first.try(:last) == 'asc'
  53. end
  54. def key_at(arg)
  55. self[arg].try(:first)
  56. end
  57. def order_at(arg)
  58. self[arg].try(:last)
  59. end
  60. def order_for(key)
  61. detect {|k, order| key.to_s == k}.try(:last)
  62. end
  63. def sort_clause(sortable_columns)
  64. if sortable_columns.is_a?(Array)
  65. sortable_columns = sortable_columns.inject({}) {|h,k| h[k]=k; h}
  66. end
  67. sql = self.collect do |k,o|
  68. if s = sortable_columns[k]
  69. s = [s] unless s.is_a?(Array)
  70. s.collect {|c| append_order(c, o)}
  71. end
  72. end.flatten.compact
  73. sql.blank? ? nil : sql
  74. end
  75. private
  76. def normalize!
  77. self.reject! {|s| s.first.blank?}
  78. self.uniq! {|s| s.first}
  79. self.collect! {|s| s = Array(s); [s.first, (s.last == false || s.last.to_s == 'desc') ? 'desc' : 'asc']}
  80. self.replace self.first(3)
  81. end
  82. # Appends ASC/DESC to the sort criterion unless it has a fixed order
  83. def append_order(criterion, order)
  84. if / (asc|desc)$/i.match?(criterion)
  85. criterion
  86. else
  87. Arel.sql "#{criterion} #{order.to_s.upcase}"
  88. end
  89. end
  90. end
  91. end