class TicketFilterSet < Hash def initialize(params, project, user = nil) @params = params.dup @dynamic_keys = [] # process static properties store :status, Status.find(:all, :order => 'rank'), :category_name => _('Status') store :priority, Priority.find(:all, :order => 'rank'), :category_name => _('Priority') store :milestone, project.milestones.find(:all, :order => 'rank'), :category_name => _('Milestone') if user && !user.public? store :my_tickets, my_filters, :category_name => _('My Tickets') end # process dynamic properties project.ticket_property_map.each do |property_type| @dynamic_keys << key = property_type.class_name.underscore.to_sym store(key, property_type.ticket_properties, :category_name => property_type.name, :type_id => property_type.id) end states = fetch(:status).values.collect{|s| s.state }.uniq state_filter = store :state, states, :category_name => _('State') if self.to_params.blank? || self.to_params == {'state' => [1, 2]} @empty = true state_filter.select(1, 2) end # inject status filter if a state is selected fetch(:status).values.each do |status| if state_filter.selected.include?(status.state_id) fetch(:status).select(status.id) end end if state_filter.selected? end def filters ([] << fetch(:state) << static_filters << dynamic_filters << fetch(:my_tickets)).flatten.compact end def search_term term = @params[:search].strip rescue '' term.blank? ? nil : '%' + term + '%' end def static_filters(selected_only = false) fetch_all(static_keys, selected_only) end def dynamic_filters(selected_only = false) fetch_all(dynamic_keys, selected_only) end def to_params filters.inject({}) do |params, filter| params[filter.name] = filter.selected.sort.dup if filter.selected? params end end def empty? @empty == true end def [](key) fetch(key) end protected UserFilter = Struct.new(:id, :name) def my_filters @my_filters ||= [ UserFilter.new(1, _('Assigned to me')), UserFilter.new(2, _('Reported by me')), UserFilter.new(3, _('Subscriptions')) ] end def store(key, collection, options = {}) super(key, TicketFilter.new(self, key, collection, @params[key], options)) end def fetch(key) super(key.to_sym) rescue nil end private def static_keys [:status, :priority, :milestone] end def dynamic_keys @dynamic_keys end def fetch_all(keys, selected_only = false) keys.collect do |key| filter = fetch(key) filter && (!selected_only || filter.selected?) ? filter : nil end.compact end class TicketFilter attr_reader :name, :values, :category_name, :name_method, :type_id, :selected def initialize(parent_set, name, values, selected, options = {}) @parent_set = parent_set @name = name.to_s @values = [values].flatten @selected = validate_selected(selected) @category_name = options[:category_name] || self.name.humanize @name_method = options[:name_method] || 'name' @type_id = options[:type_id] || :static end def selected? self.selected.any? end def include?(id) self.selected.include?(id) end def select(*values) @selected = validate_selected(@selected + values) end def to_params(id, exclusive = true) return { self.name => id } if exclusive params = @parent_set.to_params if params[self.name] && params[self.name].include?(id) params[self.name] -= [id] params.delete(self.name) if params[self.name].blank? else params[self.name] ||= [] params[self.name] << id end params end protected def validate_selected(selected) return [] unless selected [selected].flatten.collect do |value| value = Kernel.Integer(value) rescue nil value && value > 0 ? value : nil end.compact & valid_ids end def valid_ids self.values.collect{|v| v.id } end end end