Index: app/models/issue_category.rb =================================================================== --- app/models/issue_category.rb (r‚vision 17593) +++ app/models/issue_category.rb (copie de travail) @@ -28,6 +28,10 @@ safe_attributes 'name', 'assigned_to_id' scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} + scope :visible, lambda {|user = User.current| + joins(:project). + where(Project.allowed_to_condition(user, :view_issues)) + } alias :destroy_without_reassign :destroy Index: app/models/issue_query.rb =================================================================== --- app/models/issue_query.rb (r‚vision 17593) +++ app/models/issue_query.rb (copie de travail) @@ -31,7 +31,7 @@ QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true), QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true), QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'), - QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), + IssueCategoryQueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => "#{IssueCategory.table_name}.name"), QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true), QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"), QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"), @@ -124,7 +124,7 @@ add_available_filter "category_id", :type => :list_optional, - :values => lambda { project.issue_categories.collect{|s| [s.name, s.id.to_s] } } if project + :values => lambda { issue_category_values } add_available_filter "subject", :type => :text add_available_filter "description", :type => :text @@ -543,6 +543,15 @@ end end + def sql_for_category_id_field(field, operator, value) + ids = value.select {|v| v.to_s =~ /\A\d+\z/} + names = value - ids + if names.any? + ids += IssueCategory.where(:name => names).ids + end + sql_for_field(field, operator, ids.uniq, Issue.table_name, "category_id") + end + def sql_for_relations(field, operator, value, options={}) relation_options = IssueRelation::TYPES[field] return relation_options unless relation_options Index: app/models/project.rb =================================================================== --- app/models/project.rb (r‚vision 17593) +++ app/models/project.rb (copie de travail) @@ -330,6 +330,7 @@ @users = nil @shared_versions = nil @rolled_up_versions = nil + @rolled_up_issue_categories = nil @rolled_up_trackers = nil @rolled_up_statuses = nil @rolled_up_custom_fields = nil @@ -482,6 +483,13 @@ where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED) end + def rolled_up_issue_categories + @rolled_up_issue_categories ||= + IssueCategory. + joins(:project). + where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED) + end + # Returns a scope of the Versions used by the project def shared_versions if new_record? Index: app/models/query.rb =================================================================== --- app/models/query.rb (r‚vision 17593) +++ app/models/query.rb (copie de travail) @@ -162,6 +162,17 @@ end end +class IssueCategoryQueryColumn < QueryColumn + + def value_object(object) + value(object) + end + + def value(object) + object.category.try(:name) + end +end + class QueryFilter include Redmine::I18n @@ -569,7 +580,22 @@ watcher_values += users.sort_by(&:status).collect{|s| [s.name, s.id.to_s, l("status_#{User::LABEL_BY_STATUS[s.status]}")] } if User.current.allowed_to?(:view_issue_watchers, self.project) watcher_values end + + def issue_category_values + categories = + if project + project.rolled_up_issue_categories + else + IssueCategory + end + categories.visible.distinct.order(:name).pluck(:name, :name) + end + def find_category_id_filter_values(values) + ids = values.select {|v| v.to_s =~ /\A\d+\z/} + IssueCategory.where(:id => ids).distinct.order(:name).pluck(:name, :id).map {|name, id| [name, id.to_s]} + end + # Returns a scope of issue custom fields that are available as columns or filters def issue_custom_fields if project