Feature #13849 » grouped-filter-trunk-r11744.diff
app/helpers/queries_helper.rb | ||
---|---|---|
29 | 29 |
end |
30 | 30 |
end |
31 | 31 | |
32 |
def grouped_filters_options_for_select(query) |
|
33 |
option_hash = ActiveSupport::OrderedHash.new |
|
34 |
query.available_filters.each do |field, field_options| |
|
35 |
group = field_options[:group] || :non_grouped |
|
36 |
option_hash[group] ||= [] |
|
37 |
option_hash[group] << [field_options[:name], field] |
|
38 |
end |
|
39 |
options = [] |
|
40 |
option_hash.each do |k, v| |
|
41 |
options << [(k == :non_grouped) ? "etc" : l(Query::GROUP_TYPES[k]), v] |
|
42 |
end |
|
43 |
grouped_options_for_select(options) |
|
44 |
end |
|
45 | ||
32 | 46 |
def query_filters_hidden_tags(query) |
33 | 47 |
tags = ''.html_safe |
34 | 48 |
query.filters.each do |field, options| |
app/models/issue_query.rb | ||
---|---|---|
86 | 86 |
principals.uniq! |
87 | 87 |
principals.sort! |
88 | 88 |
users = principals.select {|p| p.is_a?(User)} |
89 | ||
90 |
add_available_filter "status_id",
|
|
91 |
:type => :list_status, :values => IssueStatus.sorted.all.collect{|s| [s.name, s.id.to_s] }
|
|
92 | ||
89 |
add_available_filter("status_id", |
|
90 |
:type => :list_status,
|
|
91 |
:values => IssueStatus.sorted.all.collect{|s| [s.name, s.id.to_s] },
|
|
92 |
:group => :core) |
|
93 | 93 |
if project.nil? |
94 | 94 |
project_values = [] |
95 | 95 |
if User.current.logged? && User.current.memberships.any? |
... | ... | |
97 | 97 |
end |
98 | 98 |
project_values += all_projects_values |
99 | 99 |
add_available_filter("project_id", |
100 |
:type => :list, :values => project_values |
|
100 |
:type => :list, :values => project_values, :group => :core
|
|
101 | 101 |
) unless project_values.empty? |
102 | 102 |
end |
103 | 103 | |
104 |
add_available_filter "tracker_id", |
|
105 |
:type => :list, :values => trackers.collect{|s| [s.name, s.id.to_s] } |
|
106 |
add_available_filter "priority_id", |
|
107 |
:type => :list, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] } |
|
108 | ||
104 |
add_available_filter("tracker_id", |
|
105 |
:type => :list, :values => trackers.collect{|s| [s.name, s.id.to_s] }, |
|
106 |
:group => :core) |
|
107 |
add_available_filter("priority_id", |
|
108 |
:type => :list, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s] }, |
|
109 |
:group => :core) |
|
109 | 110 |
author_values = [] |
110 | 111 |
author_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? |
111 | 112 |
author_values += users.collect{|s| [s.name, s.id.to_s] } |
112 | 113 |
add_available_filter("author_id", |
113 |
:type => :list, :values => author_values |
|
114 |
:type => :list, :values => author_values, :group => :core
|
|
114 | 115 |
) unless author_values.empty? |
115 | ||
116 | 116 |
assigned_to_values = [] |
117 | 117 |
assigned_to_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? |
118 | 118 |
assigned_to_values += (Setting.issue_group_assignment? ? |
119 | 119 |
principals : users).collect{|s| [s.name, s.id.to_s] } |
120 | 120 |
add_available_filter("assigned_to_id", |
121 |
:type => :list_optional, :values => assigned_to_values |
|
121 |
:type => :list_optional, :values => assigned_to_values, :group => :core
|
|
122 | 122 |
) unless assigned_to_values.empty? |
123 | 123 | |
124 | 124 |
group_values = Group.all.collect {|g| [g.name, g.id.to_s] } |
125 | 125 |
add_available_filter("member_of_group", |
126 |
:type => :list_optional, :values => group_values |
|
126 |
:type => :list_optional, :values => group_values, :group => :core
|
|
127 | 127 |
) unless group_values.empty? |
128 | 128 | |
129 | 129 |
role_values = Role.givable.collect {|r| [r.name, r.id.to_s] } |
130 | 130 |
add_available_filter("assigned_to_role", |
131 |
:type => :list_optional, :values => role_values |
|
131 |
:type => :list_optional, :values => role_values, :group => :core
|
|
132 | 132 |
) unless role_values.empty? |
133 | 133 | |
134 | 134 |
if versions.any? |
135 |
add_available_filter "fixed_version_id",
|
|
135 |
add_available_filter("fixed_version_id",
|
|
136 | 136 |
:type => :list_optional, |
137 |
:values => versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] } |
|
137 |
:values => versions.sort.collect{|s| ["#{s.project.name} - #{s.name}", s.id.to_s] }, |
|
138 |
:group => :core) |
|
138 | 139 |
end |
139 | 140 | |
140 | 141 |
if categories.any? |
141 |
add_available_filter "category_id",
|
|
142 |
add_available_filter("category_id",
|
|
142 | 143 |
:type => :list_optional, |
143 |
:values => categories.collect{|s| [s.name, s.id.to_s] } |
|
144 |
:values => categories.collect{|s| [s.name, s.id.to_s] }, |
|
145 |
:group => :core) |
|
144 | 146 |
end |
145 | 147 | |
146 |
add_available_filter "subject", :type => :text
|
|
147 |
add_available_filter "created_on", :type => :date_past
|
|
148 |
add_available_filter "updated_on", :type => :date_past
|
|
149 |
add_available_filter "closed_on", :type => :date_past
|
|
150 |
add_available_filter "start_date", :type => :date
|
|
151 |
add_available_filter "due_date", :type => :date
|
|
152 |
add_available_filter "estimated_hours", :type => :float
|
|
153 |
add_available_filter "done_ratio", :type => :integer
|
|
148 |
add_available_filter("subject", :type => :text, :group => :core)
|
|
149 |
add_available_filter("created_on", :type => :date_past, :group => :core)
|
|
150 |
add_available_filter("updated_on", :type => :date_past, :group => :core)
|
|
151 |
add_available_filter("closed_on", :type => :date_past, :group => :core)
|
|
152 |
add_available_filter("start_date", :type => :date, :group => :core)
|
|
153 |
add_available_filter("due_date", :type => :date, :group => :core)
|
|
154 |
add_available_filter("estimated_hours", :type => :float, :group => :core)
|
|
155 |
add_available_filter("done_ratio", :type => :integer, :group => :core)
|
|
154 | 156 | |
155 | 157 |
if User.current.allowed_to?(:set_issues_private, nil, :global => true) || |
156 | 158 |
User.current.allowed_to?(:set_own_issues_private, nil, :global => true) |
157 |
add_available_filter "is_private",
|
|
159 |
add_available_filter("is_private",
|
|
158 | 160 |
:type => :list, |
159 |
:values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]] |
|
161 |
:values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], |
|
162 |
:group => :core) |
|
160 | 163 |
end |
161 | 164 | |
162 | 165 |
if User.current.logged? |
163 |
add_available_filter "watcher_id", |
|
164 |
:type => :list, :values => [["<< #{l(:label_me)} >>", "me"]] |
|
166 |
add_available_filter("watcher_id", |
|
167 |
:type => :list, :values => [["<< #{l(:label_me)} >>", "me"]], |
|
168 |
:group => :core) |
|
165 | 169 |
end |
166 | 170 | |
167 | 171 |
if subprojects.any? |
168 |
add_available_filter "subproject_id",
|
|
172 |
add_available_filter("subproject_id",
|
|
169 | 173 |
:type => :list_subprojects, |
170 |
:values => subprojects.collect{|s| [s.name, s.id.to_s] } |
|
174 |
:values => subprojects.collect{|s| [s.name, s.id.to_s] }, |
|
175 |
:group => :core) |
|
171 | 176 |
end |
172 | 177 | |
173 | 178 |
add_custom_fields_filters(issue_custom_fields) |
... | ... | |
175 | 180 |
add_associations_custom_fields_filters :project, :author, :assigned_to, :fixed_version |
176 | 181 | |
177 | 182 |
IssueRelation::TYPES.each do |relation_type, options| |
178 |
add_available_filter relation_type, :type => :relation, :label => options[:name] |
|
183 |
add_available_filter(relation_type, :type => :relation, |
|
184 |
:label => options[:name], :group => :relation) |
|
179 | 185 |
end |
180 | 186 | |
181 | 187 |
Tracker.disabled_core_fields(trackers).each {|field| |
app/models/query.rb | ||
---|---|---|
116 | 116 |
class StatementInvalid < ::ActiveRecord::StatementInvalid |
117 | 117 |
end |
118 | 118 | |
119 |
GROUP_TYPES = { |
|
120 |
:core => :field_core_fields, |
|
121 |
:relation => :label_related_issues, |
|
122 |
:custom_field => :label_custom_field_plural, |
|
123 |
}.freeze |
|
124 | ||
119 | 125 |
belongs_to :project |
120 | 126 |
belongs_to :user |
121 | 127 |
serialize :filters |
... | ... | |
760 | 766 |
filter_id = "#{assoc}.#{filter_id}" |
761 | 767 |
filter_name = l("label_attribute_of_#{assoc}", :name => filter_name) |
762 | 768 |
end |
763 |
add_available_filter filter_id, options.merge({
|
|
769 |
add_available_filter(filter_id, options.merge({
|
|
764 | 770 |
:name => filter_name, |
765 | 771 |
:format => field.field_format, |
766 |
:field => field |
|
767 |
}) |
|
772 |
:field => field, |
|
773 |
:group => :custom_field |
|
774 |
})) |
|
768 | 775 |
end |
769 | 776 |
end |
770 | 777 |
app/models/time_entry_query.rb | ||
---|---|---|
36 | 36 |
end |
37 | 37 | |
38 | 38 |
def initialize_available_filters |
39 |
add_available_filter "spent_on", :type => :date_past |
|
40 | ||
39 |
add_available_filter("spent_on", :type => :date_past, :group => :core) |
|
41 | 40 |
principals = [] |
42 | 41 |
if project |
43 | 42 |
principals += project.principals.sort |
44 | 43 |
unless project.leaf? |
45 | 44 |
subprojects = project.descendants.visible.all |
46 | 45 |
if subprojects.any? |
47 |
add_available_filter "subproject_id",
|
|
46 |
add_available_filter("subproject_id",
|
|
48 | 47 |
:type => :list_subprojects, |
49 |
:values => subprojects.collect{|s| [s.name, s.id.to_s] } |
|
48 |
:values => subprojects.collect{|s| [s.name, s.id.to_s] }, |
|
49 |
:group => :core) |
|
50 | 50 |
principals += Principal.member_of(subprojects) |
51 | 51 |
end |
52 | 52 |
end |
... | ... | |
61 | 61 |
end |
62 | 62 |
project_values += all_projects_values |
63 | 63 |
add_available_filter("project_id", |
64 |
:type => :list, :values => project_values |
|
64 |
:type => :list, :values => project_values, :group => :core
|
|
65 | 65 |
) unless project_values.empty? |
66 | 66 |
end |
67 | 67 |
end |
... | ... | |
73 | 73 |
users_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged? |
74 | 74 |
users_values += users.collect{|s| [s.name, s.id.to_s] } |
75 | 75 |
add_available_filter("user_id", |
76 |
:type => :list_optional, :values => users_values |
|
76 |
:type => :list_optional, :values => users_values, :group => :core
|
|
77 | 77 |
) unless users_values.empty? |
78 | 78 | |
79 | 79 |
activities = (project ? project.activities : TimeEntryActivity.shared.active) |
80 | 80 |
add_available_filter("activity_id", |
81 |
:type => :list, :values => activities.map {|a| [a.name, a.id.to_s]} |
|
81 |
:type => :list, :values => activities.map {|a| [a.name, a.id.to_s]}, |
|
82 |
:group => :core |
|
82 | 83 |
) unless activities.empty? |
83 | 84 | |
84 |
add_available_filter "comments", :type => :text
|
|
85 |
add_available_filter "hours", :type => :float
|
|
85 |
add_available_filter("comments", :type => :text, :group => :core)
|
|
86 |
add_available_filter("hours", :type => :float, :group => :core)
|
|
86 | 87 | |
87 | 88 |
add_custom_fields_filters(TimeEntryCustomField.where(:is_filter => true).all) |
88 | 89 |
add_associations_custom_fields_filters :project, :issue, :user |
app/views/queries/_filters.html.erb | ||
---|---|---|
20 | 20 |
</td> |
21 | 21 |
<td class="add-filter"> |
22 | 22 |
<%= label_tag('add_filter_select', l(:label_filter_add)) %> |
23 |
<%= select_tag 'add_filter_select', filters_options_for_select(query), :name => nil %> |
|
23 |
<%= select_tag('add_filter_select', |
|
24 |
content_tag(:option).html_safe + |
|
25 |
grouped_filters_options_for_select(query), |
|
26 |
:name => nil) %> |
|
24 | 27 |
</td> |
25 | 28 |
</tr> |
26 | 29 |
</table> |
public/javascripts/application.js | ||
---|---|---|
106 | 106 |
} |
107 | 107 |
$('#cb_'+fieldId).attr('checked', true); |
108 | 108 |
toggleFilter(field); |
109 |
$('#add_filter_select').val('').children('option').each(function() { |
|
109 |
$('#add_filter_select').val('').children('optgroup').children('option').each(function() {
|
|
110 | 110 |
if ($(this).attr('value') == field) { |
111 | 111 |
$(this).attr('disabled', true); |
112 | 112 |
} |