Feature #7867 » add-author-group-filtering.patch
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 37 | 37 |
group = query.is_a?(IssueQuery) ? :label_relations : nil |
| 38 | 38 |
elsif %w(member_of_group assigned_to_role).include?(field) |
| 39 | 39 |
group = :field_assigned_to |
| 40 |
elsif %w(author_group author_role).include?(field) |
|
| 41 |
group = :field_author |
|
| 40 | 42 |
elsif field_options[:type] == :date_past || field_options[:type] == :date |
| 41 | 43 |
group = :label_date |
| 42 | 44 |
elsif %w(estimated_hours spent_time).include?(field) |
| app/models/issue_query.rb | ||
|---|---|---|
| 180 | 180 |
:type => :list_optional, |
| 181 | 181 |
:values => lambda {Role.givable.pluck(:name, :id).map {|name, id| [name, id.to_s]}}
|
| 182 | 182 |
) |
| 183 |
add_available_filter( |
|
| 184 |
"author_group", |
|
| 185 |
:type => :list, |
|
| 186 |
:values => lambda {Group.givable.visible.pluck(:name, :id).map {|name, id| [name, id.to_s]}}
|
|
| 187 |
) |
|
| 188 |
add_available_filter( |
|
| 189 |
"author_role", |
|
| 190 |
:type => :list, |
|
| 191 |
:values => lambda {Role.givable.pluck(:name, :id).map {|name, id| [name, id.to_s]}}
|
|
| 192 |
) |
|
| 183 | 193 |
add_available_filter( |
| 184 | 194 |
"fixed_version_id", |
| 185 | 195 |
:type => :list_optional_with_history, :values => lambda {fixed_version_values}
|
| ... | ... | |
| 592 | 602 |
end |
| 593 | 603 |
end |
| 594 | 604 | |
| 605 |
def sql_for_author_group_field(field, operator, value) |
|
| 606 |
groups = if value.empty? |
|
| 607 |
Group.givable |
|
| 608 |
else |
|
| 609 |
Group.where(:id => value).to_a |
|
| 610 |
end |
|
| 611 | ||
| 612 |
author_groups = groups.inject([]) do |user_ids, group| |
|
| 613 |
user_ids + group.user_ids + [group.id] |
|
| 614 |
end.uniq.compact.sort.collect(&:to_s) |
|
| 615 | ||
| 616 |
'(' + sql_for_field("author_id", operator, author_groups, Issue.table_name, "author_id", false) + ')'
|
|
| 617 |
end |
|
| 618 | ||
| 619 |
def sql_for_author_role_field(field, operator, value) |
|
| 620 |
role_cond = |
|
| 621 |
if value.any? |
|
| 622 |
"#{MemberRole.table_name}.role_id IN (" + value.collect{|val| "'#{self.class.connection.quote_string(val)}'"}.join(",") + ")"
|
|
| 623 |
else |
|
| 624 |
"1=0" |
|
| 625 |
end |
|
| 626 |
sw = operator == "!" ? 'NOT' : '' |
|
| 627 |
nl = operator == "!" ? "#{Issue.table_name}.author_id IS NULL OR" : ''
|
|
| 628 |
subquery = |
|
| 629 |
"SELECT 1" + |
|
| 630 |
" FROM #{Member.table_name} inner join #{MemberRole.table_name} on members.id = member_roles.member_id" +
|
|
| 631 |
" WHERE #{Issue.table_name}.project_id = #{Member.table_name}.project_id AND #{Member.table_name}.user_id = #{Issue.table_name}.author_id AND #{role_cond}"
|
|
| 632 |
"(#{nl} #{sw} EXISTS (#{subquery}))"
|
|
| 633 |
end |
|
| 634 | ||
| 595 | 635 |
def sql_for_fixed_version_status_field(field, operator, value) |
| 596 | 636 |
where = sql_for_field(field, operator, value, Version.table_name, "status") |
| 597 | 637 |
version_id_scope = project ? project.shared_versions : Version.visible |
| config/locales/en.yml | ||
|---|---|---|
| 376 | 376 |
field_parent_issue_subject: Parent task subject |
| 377 | 377 |
field_member_of_group: "Assignee's group" |
| 378 | 378 |
field_assigned_to_role: "Assignee's role" |
| 379 |
field_author_group: "Author's group" |
|
| 380 |
field_author_role: "Author's role" |
|
| 379 | 381 |
field_text: Text field |
| 380 | 382 |
field_visible: Visible |
| 381 | 383 |
field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text" |
| config/locales/ja.yml | ||
|---|---|---|
| 334 | 334 |
field_parent_issue: 親チケット |
| 335 | 335 |
field_member_of_group: 担当者のグループ |
| 336 | 336 |
field_assigned_to_role: 担当者のロール |
| 337 |
field_author_group: 作成者のグループ |
|
| 338 |
field_author_role: 作成者のロール |
|
| 337 | 339 |
field_text: テキスト |
| 338 | 340 |
field_visible: 表示 |
| 339 | 341 |
field_warn_on_leaving_unsaved: データを保存せずにページから移動するときに警告 |
| test/helpers/queries_helper_test.rb | ||
|---|---|---|
| 117 | 117 |
assert_select_in options, 'option[value=?]', "cf_#{i_cf.id}.cf_#{u_cf.id}", text: "User's Phone number"
|
| 118 | 118 |
assert_select_in options, 'optgroup[label=?]', 'User', 1 |
| 119 | 119 |
end |
| 120 | ||
| 121 |
def test_filters_options_for_select_should_group_author_filters |
|
| 122 |
with_locale 'en' do |
|
| 123 |
options = filters_options_for_select(IssueQuery.new) |
|
| 124 |
assert_select_in options, 'optgroup[label=?]', "Author", 1 |
|
| 125 |
assert_select_in options, 'optgroup > option[value=author_group]', :text => "Author's group" |
|
| 126 |
assert_select_in options, 'optgroup > option[value=author_role]', :text => "Author's role" |
|
| 127 |
end |
|
| 128 |
end |
|
| 120 | 129 |
end |
| test/unit/query_test.rb | ||
|---|---|---|
| 2788 | 2788 |
assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous', '5']) |
| 2789 | 2789 |
end |
| 2790 | 2790 | |
| 2791 |
def test_available_filters_should_include_author_group_filter |
|
| 2792 |
query = IssueQuery.new |
|
| 2793 |
assert query.available_filters.key?("author_group")
|
|
| 2794 |
assert_equal :list, query.available_filters["author_group"][:type] |
|
| 2795 |
assert query.available_filters["author_group"][:values].present? |
|
| 2796 |
assert_equal Group.givable.sort.map {|g| [g.name, g.id.to_s]},
|
|
| 2797 |
query.available_filters["author_group"][:values].sort |
|
| 2798 |
end |
|
| 2799 | ||
| 2800 |
def test_available_filters_should_include_author_role_filter |
|
| 2801 |
query = IssueQuery.new |
|
| 2802 |
assert query.available_filters.key?("author_role")
|
|
| 2803 |
assert_equal :list, query.available_filters["author_role"][:type] |
|
| 2804 | ||
| 2805 |
assert query.available_filters["author_role"][:values].include?(['Manager', '1']) |
|
| 2806 |
assert query.available_filters["author_role"][:values].include?(['Developer', '2']) |
|
| 2807 |
assert query.available_filters["author_role"][:values].include?(['Reporter', '3']) |
|
| 2808 | ||
| 2809 |
assert ! query.available_filters["author_role"][:values].include?(['Non member', '4']) |
|
| 2810 |
assert ! query.available_filters["author_role"][:values].include?(['Anonymous', '5']) |
|
| 2811 |
end |
|
| 2812 | ||
| 2791 | 2813 |
def test_available_filters_should_include_custom_field_according_to_user_visibility |
| 2792 | 2814 |
visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true) |
| 2793 | 2815 |
hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1]) |
| ... | ... | |
| 2958 | 2980 |
assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query |
| 2959 | 2981 |
end |
| 2960 | 2982 | |
| 2983 |
def test_author_group_filter_should_return_issues_with_or_without_author_in_group |
|
| 2984 |
project = Project.generate! |
|
| 2985 |
author = User.generate! |
|
| 2986 |
author_group = Group.generate! |
|
| 2987 |
not_author_group = Group.generate! |
|
| 2988 |
author.groups << author_group |
|
| 2989 |
issues = 3.times.collect { Issue.generate!(:project => project, :author => author) }
|
|
| 2990 | ||
| 2991 |
query = IssueQuery.new(:name => '_', :project => project) |
|
| 2992 |
query.add_filter('author_group', '=', [author_group.id.to_s])
|
|
| 2993 |
assert_equal 3, query.issues.count |
|
| 2994 |
assert_query_result issues, query |
|
| 2995 | ||
| 2996 |
query = IssueQuery.new(:name => '_', :project => project) |
|
| 2997 |
query.add_filter('author_group', '!', [not_author_group.id.to_s])
|
|
| 2998 |
assert_equal 3, query.issues.count |
|
| 2999 |
assert_query_result issues, query |
|
| 3000 |
end |
|
| 3001 | ||
| 3002 |
def test_author_role_filter_should_return_issues_with_or_without_author_in_role |
|
| 3003 |
project = Project.generate! |
|
| 3004 |
author = User.generate! |
|
| 3005 |
manager_role = Role.find_by_name('Manager')
|
|
| 3006 |
developer_role = Role.find_by_name('Developer')
|
|
| 3007 |
User.add_to_project(author, project, manager_role) |
|
| 3008 |
issues = 3.times.collect { Issue.generate!(:project => project, :author => author) }
|
|
| 3009 | ||
| 3010 |
query = IssueQuery.new(:name => 'issues generated by manager', :project => project) |
|
| 3011 |
query.add_filter('author_role', '=', [manager_role.id.to_s])
|
|
| 3012 |
assert_equal 3, query.issues.count |
|
| 3013 |
assert_query_result issues, query |
|
| 3014 | ||
| 3015 |
query = IssueQuery.new(:name => 'issues does not generated by developer', :project => project) |
|
| 3016 |
query.add_filter('author_role', '!', [developer_role.id.to_s])
|
|
| 3017 |
assert_equal 3, query.issues.count |
|
| 3018 |
assert_query_result issues, query |
|
| 3019 |
end |
|
| 3020 | ||
| 2961 | 3021 |
def test_query_column_should_accept_a_symbol_as_caption |
| 2962 | 3022 |
set_language_if_valid 'en' |
| 2963 | 3023 |
c = QueryColumn.new('foo', :caption => :general_text_Yes)
|