mirror of
				https://github.com/redmine/redmine.git
				synced 2025-10-31 02:15:52 +01:00 
			
		
		
		
	
		
			
	
	
		
			105 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			105 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|  | # Redmine - project management software | ||
|  | # Copyright (C) 2006-2017  Jean-Philippe Lang | ||
|  | # | ||
|  | # 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]} | ||
|  |       elsif arg.is_a?(Hash) | ||
|  |         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 | ||
|  |       self.collect {|k,o| k + (o == 'desc' ? ':desc' : '')}.join(',') | ||
|  |     end | ||
|  | 
 | ||
|  |     def to_a | ||
|  |       Array.new(self) | ||
|  |     end | ||
|  | 
 | ||
|  |     def add!(key, asc) | ||
|  |       key = key.to_s | ||
|  |       delete_if {|k,o| k == key} | ||
|  |       prepend([key, asc]) | ||
|  |       normalize! | ||
|  |     end | ||
|  | 
 | ||
|  |     def add(*args) | ||
|  |       self.class.new(self).add!(*args) | ||
|  |     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) | ||
|  |         sortable_columns = sortable_columns.inject({}) {|h,k| h[k]=k; h} | ||
|  |       end | ||
|  | 
 | ||
|  |       sql = self.collect do |k,o| | ||
|  |         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! | ||
|  |       self.collect! {|s| s = Array(s); [s.first, (s.last == false || s.last.to_s == 'desc') ? 'desc' : 'asc']} | ||
|  |       self.slice!(3) | ||
|  |       self | ||
|  |     end | ||
|  | 
 | ||
|  |     # Appends ASC/DESC to the sort criterion unless it has a fixed order | ||
|  |     def append_order(criterion, order) | ||
|  |       if criterion =~ / (asc|desc)$/i | ||
|  |         criterion | ||
|  |       else | ||
|  |         "#{criterion} #{order.to_s.upcase}" | ||
|  |       end | ||
|  |     end | ||
|  |   end | ||
|  | end |