| 
									
										
										
										
											2019-03-16 09:37:35 +00:00
										 |  |  | # frozen_string_literal: true | 
					
						
							| 
									
										
										
										
											2019-03-15 01:32:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  | # Redmine - project management software | 
					
						
							| 
									
										
										
										
											2024-02-26 22:55:54 +00:00
										 |  |  | # Copyright (C) 2006-  Jean-Philippe Lang | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | # modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | # as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | # of the License, or (at your option) any later version. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | # but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | # GNU General Public License for more details. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | # along with this program; if not, write to the Free Software | 
					
						
							|  |  |  | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module Redmine | 
					
						
							|  |  |  |   class SortCriteria < Array | 
					
						
							|  |  |  |     def initialize(arg=nil) | 
					
						
							|  |  |  |       super() | 
					
						
							|  |  |  |       if arg.is_a?(Array) | 
					
						
							|  |  |  |         replace arg | 
					
						
							|  |  |  |       elsif arg.is_a?(String) | 
					
						
							|  |  |  |         replace arg.split(',').collect {|s| s.split(':')[0..1]} | 
					
						
							| 
									
										
										
										
											2017-06-03 08:44:29 +00:00
										 |  |  |       elsif arg.respond_to?(:values) | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |         replace arg.values | 
					
						
							|  |  |  |       elsif arg | 
					
						
							|  |  |  |         raise ArgumentError.new("SortCriteria#new takes an Array, String or Hash, not a #{arg.class.name}.") | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       normalize! | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def to_param | 
					
						
							| 
									
										
										
										
											2024-08-12 08:36:05 +00:00
										 |  |  |       self.collect {|k, o| k + (o == 'desc' ? ':desc' : '')}.join(',') | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def to_a | 
					
						
							|  |  |  |       Array.new(self) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def add!(key, asc) | 
					
						
							|  |  |  |       key = key.to_s | 
					
						
							| 
									
										
										
										
											2024-08-12 08:36:05 +00:00
										 |  |  |       delete_if {|k, o| k == key} | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |       prepend([key, asc]) | 
					
						
							|  |  |  |       normalize! | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-21 05:57:01 +00:00
										 |  |  |     def add(*) | 
					
						
							|  |  |  |       self.class.new(self).add!(*) | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def first_key | 
					
						
							|  |  |  |       first.try(:first) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def first_asc? | 
					
						
							|  |  |  |       first.try(:last) == 'asc' | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def key_at(arg) | 
					
						
							|  |  |  |       self[arg].try(:first) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def order_at(arg) | 
					
						
							|  |  |  |       self[arg].try(:last) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def order_for(key) | 
					
						
							|  |  |  |       detect {|k, order| key.to_s == k}.try(:last) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def sort_clause(sortable_columns) | 
					
						
							|  |  |  |       if sortable_columns.is_a?(Array) | 
					
						
							| 
									
										
										
										
											2024-08-12 08:36:05 +00:00
										 |  |  |         sortable_columns = sortable_columns.inject({}) {|h, k| h[k]=k; h} | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-12 08:36:05 +00:00
										 |  |  |       sql = self.collect do |k, o| | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |         if s = sortable_columns[k] | 
					
						
							|  |  |  |           s = [s] unless s.is_a?(Array) | 
					
						
							|  |  |  |           s.collect {|c| append_order(c, o)} | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end.flatten.compact | 
					
						
							|  |  |  |       sql.blank? ? nil : sql | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def normalize! | 
					
						
							| 
									
										
										
										
											2020-11-21 13:52:12 +00:00
										 |  |  |       self.reject! {|s| s.first.blank?} | 
					
						
							|  |  |  |       self.uniq! {|s| s.first} | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |       self.collect! {|s| s = Array(s); [s.first, (s.last == false || s.last.to_s == 'desc') ? 'desc' : 'asc']} | 
					
						
							| 
									
										
										
										
											2018-09-20 02:08:15 +00:00
										 |  |  |       self.replace self.first(3) | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Appends ASC/DESC to the sort criterion unless it has a fixed order | 
					
						
							|  |  |  |     def append_order(criterion, order) | 
					
						
							| 
									
										
										
										
											2019-03-27 02:15:24 +00:00
										 |  |  |       if / (asc|desc)$/i.match?(criterion) | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |         criterion | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											2018-06-23 05:19:07 +00:00
										 |  |  |         Arel.sql "#{criterion} #{order.to_s.upcase}" | 
					
						
							| 
									
										
										
										
											2017-03-13 19:17:59 +00:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |