Patch #1898 » watcher_filter.diff
app/models/query.rb | ||
---|---|---|
76 | 76 |
"<t-" => :label_more_than_ago, |
77 | 77 |
"t-" => :label_ago, |
78 | 78 |
"~" => :label_contains, |
79 |
"!~" => :label_not_contains } |
|
79 |
"!~" => :label_not_contains, |
|
80 |
"<w" => :label_equals, |
|
81 |
">w" => :label_not_equals} |
|
80 | 82 | |
81 | 83 |
cattr_reader :operators |
82 | 84 |
|
83 | 85 |
@@operators_by_filter_type = { :list => [ "=", "!" ], |
86 |
:list_watcher => [ "<w", ">w" ], |
|
84 | 87 |
:list_status => [ "o", "=", "!", "c", "*" ], |
85 | 88 |
:list_optional => [ "=", "!", "!*", "*" ], |
86 | 89 |
:list_subprojects => [ "*", "!*", "=" ], |
... | ... | |
107 | 110 |
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"), |
108 | 111 |
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio"), |
109 | 112 |
QueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on", :default_order => 'desc'), |
113 |
QueryColumn.new(:watcher), |
|
110 | 114 |
] |
111 | 115 |
cattr_reader :available_columns |
112 | 116 |
|
... | ... | |
165 | 169 |
end |
166 | 170 |
@available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty? |
167 | 171 |
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty? |
172 |
@available_filters["watcher_id"] = { :type => :list_watcher, :order => 15, :values => user_values } unless user_values.empty? |
|
168 | 173 |
|
169 | 174 |
if project |
170 | 175 |
# project specific filters |
... | ... | |
305 | 310 |
end |
306 | 311 |
|
307 | 312 |
# "me" value subsitution |
308 |
if %w(assigned_to_id author_id).include?(field) |
|
313 |
if %w(assigned_to_id author_id watcher_id).include?(field)
|
|
309 | 314 |
v.push(User.current.logged? ? User.current.id.to_s : "0") if v.delete("me") |
310 | 315 |
end |
311 | 316 |
|
... | ... | |
353 | 358 |
sql = sql + "#{db_table}.#{db_field} LIKE '%#{connection.quote_string(v.first)}%'" |
354 | 359 |
when "!~" |
355 | 360 |
sql = sql + "#{db_table}.#{db_field} NOT LIKE '%#{connection.quote_string(v.first)}%'" |
361 |
when "<w" |
|
362 |
sql = sql + "#{Issue.table_name}.id IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" if field == "watcher_id" |
|
363 |
when ">w" |
|
364 |
sql = sql + "#{Issue.table_name}.id IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id NOT IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" if field == "watcher_id" |
|
356 | 365 |
end |
357 | 366 |
sql << ')' |
358 | 367 |
filters_clauses << sql |
app/views/queries/_filters.rhtml | ||
---|---|---|
74 | 74 |
<td> |
75 | 75 |
<div id="div_values_<%= field %>" style="display:none;"> |
76 | 76 |
<% case options[:type] |
77 |
when :list, :list_optional, :list_status, :list_subprojects %> |
|
77 |
when :list, :list_optional, :list_status, :list_subprojects, :list_watcher %>
|
|
78 | 78 |
<select <%= "multiple=true" if query.values_for(field) and query.values_for(field).length > 1 %> name="values[<%= field %>][]" id="values_<%= field %>" class="select-small" style="vertical-align: top;"> |
79 | 79 |
<%= options_for_select options[:values], query.values_for(field) %> |
80 | 80 |
</select> |
lang/en.yml | ||
---|---|---|
183 | 183 |
field_default_value: Default value |
184 | 184 |
field_comments_sorting: Display comments |
185 | 185 |
field_parent_title: Parent page |
186 |
field_watcher: Watcher |
|
186 | 187 | |
187 | 188 |
setting_app_title: Application title |
188 | 189 |
setting_app_subtitle: Application subtitle |
189 |
- |
lang/bg.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Пренасочване на съществуващи линкове |
166 | 166 |
field_estimated_hours: Изчислено време |
167 | 167 |
field_default_value: Стойност по подразбиране |
168 |
field_watcher: Watcher |
|
168 | 169 | |
169 | 170 |
setting_app_title: Заглавие |
170 | 171 |
setting_app_subtitle: Описание |
lang/cs.yml | ||
---|---|---|
183 | 183 |
field_searchable: Umožnit vyhledávání |
184 | 184 |
field_default_value: Výchozí hodnota |
185 | 185 |
field_comments_sorting: Zobrazit komentáře |
186 |
field_watcher: Watcher |
|
186 | 187 | |
187 | 188 |
setting_app_title: Název aplikace |
188 | 189 |
setting_app_subtitle: Podtitulek aplikace |
lang/da.yml | ||
---|---|---|
177 | 177 |
field_time_zone: Tids zone |
178 | 178 |
field_searchable: Søgbar |
179 | 179 |
field_default_value: Standard værdi |
180 |
field_watcher: Watcher |
|
180 | 181 | |
181 | 182 |
setting_app_title: Applikations titel |
182 | 183 |
setting_app_subtitle: Applikations undertekst |
lang/de.yml | ||
---|---|---|
180 | 180 |
field_searchable: Durchsuchbar |
181 | 181 |
field_default_value: Standardwert |
182 | 182 |
field_comments_sorting: Kommentare anzeigen |
183 |
field_watcher: Watcher |
|
183 | 184 | |
184 | 185 |
setting_app_title: Applikations-Titel |
185 | 186 |
setting_app_subtitle: Applikations-Untertitel |
lang/es.yml | ||
---|---|---|
159 | 159 |
field_issue_to_id: Petición Relacionada |
160 | 160 |
field_delay: Retraso |
161 | 161 |
field_default_value: Estado por defecto |
162 |
field_watcher: Watcher |
|
162 | 163 | |
163 | 164 |
setting_app_title: Título de la aplicación |
164 | 165 |
setting_app_subtitle: Subtítulo de la aplicación |
lang/fi.yml | ||
---|---|---|
177 | 177 |
field_time_zone: Aikavyöhyke |
178 | 178 |
field_searchable: Haettava |
179 | 179 |
field_default_value: Vakioarvo |
180 |
field_watcher: Watcher |
|
180 | 181 | |
181 | 182 |
setting_app_title: Ohjelman otsikko |
182 | 183 |
setting_app_subtitle: Ohjelman alaotsikko |
lang/fr.yml | ||
---|---|---|
184 | 184 |
field_default_value: Valeur par défaut |
185 | 185 |
field_comments_sorting: Afficher les commentaires |
186 | 186 |
field_parent_title: Page parent |
187 |
field_watcher: Watcher |
|
187 | 188 | |
188 | 189 |
setting_app_title: Titre de l'application |
189 | 190 |
setting_app_subtitle: Sous-titre de l'application |
lang/he.yml | ||
---|---|---|
168 | 168 |
field_estimated_hours: זמן משוער |
169 | 169 |
field_column_names: עמודות |
170 | 170 |
field_default_value: ערך ברירת מחדל |
171 |
field_watcher: Watcher |
|
171 | 172 | |
172 | 173 |
setting_app_title: כותרת ישום |
173 | 174 |
setting_app_subtitle: תת-כותרת ישום |
lang/hu.yml | ||
---|---|---|
180 | 180 |
field_searchable: Kereshető |
181 | 181 |
field_default_value: Alapértelmezett érték |
182 | 182 |
field_comments_sorting: Feljegyzések megjelenítése |
183 |
field_watcher: Watcher |
|
183 | 184 | |
184 | 185 |
setting_app_title: Alkalmazás címe |
185 | 186 |
setting_app_subtitle: Alkalmazás alcíme |
lang/it.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Redirige i collegamenti esistenti |
166 | 166 |
field_estimated_hours: Tempo stimato |
167 | 167 |
field_default_value: Stato predefinito |
168 |
field_watcher: Watcher |
|
168 | 169 | |
169 | 170 |
setting_app_title: Titolo applicazione |
170 | 171 |
setting_app_subtitle: Sottotitolo applicazione |
lang/ja.yml | ||
---|---|---|
166 | 166 |
field_redirect_existing_links: 既存のリンクをリダイレクトする |
167 | 167 |
field_estimated_hours: 予定工数 |
168 | 168 |
field_default_value: デフォルトのステータス |
169 |
field_watcher: Watcher |
|
169 | 170 | |
170 | 171 |
setting_app_title: アプリケーションのタイトル |
171 | 172 |
setting_app_subtitle: アプリケーションのサブタイトル |
lang/ko.yml | ||
---|---|---|
168 | 168 |
field_estimated_hours: 추정시간 |
169 | 169 |
field_column_names: 컬럼 |
170 | 170 |
field_default_value: 기본값 |
171 |
field_watcher: Watcher |
|
171 | 172 | |
172 | 173 |
setting_app_title: 레드마인 제목 |
173 | 174 |
setting_app_subtitle: 레드마인 부제목 |
lang/lt.yml | ||
---|---|---|
176 | 176 |
field_time_zone: Laiko juosta |
177 | 177 |
field_searchable: Randamas |
178 | 178 |
field_default_value: Numatytoji vertė |
179 |
field_watcher: Watcher |
|
180 | ||
179 | 181 |
setting_app_title: Programos pavadinimas |
180 | 182 |
setting_app_subtitle: Programos paantraštė |
181 | 183 |
setting_welcome_text: Pasveikinimas |
lang/no.yml | ||
---|---|---|
182 | 182 |
field_searchable: Søkbar |
183 | 183 |
field_default_value: Standardverdi |
184 | 184 |
field_comments_sorting: Vis kommentarer |
185 |
field_watcher: Watcher |
|
185 | 186 | |
186 | 187 |
setting_app_title: Applikasjonstittel |
187 | 188 |
setting_app_subtitle: Applikasjonens undertittel |
lang/pl.yml | ||
---|---|---|
159 | 159 |
field_issue_to_id: Powiązania zagadnienia |
160 | 160 |
field_delay: Opóźnienie |
161 | 161 |
field_default_value: Domyślny |
162 |
field_watcher: Watcher |
|
162 | 163 | |
163 | 164 |
setting_app_title: Tytuł aplikacji |
164 | 165 |
setting_app_subtitle: Podtytuł aplikacji |
lang/pt-br.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Redirecionar links existentes |
166 | 166 |
field_estimated_hours: Tempo estimado |
167 | 167 |
field_default_value: Padrão |
168 |
field_watcher: Watcher |
|
168 | 169 |
|
169 | 170 |
setting_app_title: Título da aplicação |
170 | 171 |
setting_app_subtitle: Sub-título da aplicação |
lang/pt.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Redirect existing links |
166 | 166 |
field_estimated_hours: Estimated time |
167 | 167 |
field_default_value: Padrão |
168 |
field_watcher: Watcher |
|
168 | 169 | |
169 | 170 |
setting_app_title: Título da aplicação |
170 | 171 |
setting_app_subtitle: Sub-título da aplicação |
lang/ro.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Redirectare linkuri existente |
166 | 166 |
field_estimated_hours: Timpul estimat |
167 | 167 |
field_default_value: Default value |
168 |
field_watcher: Watcher |
|
168 | 169 | |
169 | 170 |
setting_app_title: Titlul aplicatiei |
170 | 171 |
setting_app_subtitle: Subtitlul aplicatiei |
lang/ru.yml | ||
---|---|---|
178 | 178 |
field_default_value: Значение по умолчанию |
179 | 179 |
field_time_zone: Часовой пояс |
180 | 180 |
field_searchable: Доступно для поиска |
181 |
field_watcher: Watcher |
|
181 | 182 | |
182 | 183 |
setting_app_title: Название приложения |
183 | 184 |
setting_app_subtitle: Подзаголовок приложения |
lang/sr.yml | ||
---|---|---|
170 | 170 |
field_estimated_hours: Procenjeno vreme |
171 | 171 |
field_column_names: Kolone |
172 | 172 |
field_default_value: Default value |
173 |
field_watcher: Watcher |
|
173 | 174 | |
174 | 175 |
setting_app_title: Naziv aplikacije |
175 | 176 |
setting_app_subtitle: Podnaslov aplikacije |
lang/sv.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Redirect existing links |
166 | 166 |
field_estimated_hours: Estimated time |
167 | 167 |
field_default_value: Default value |
168 |
field_watcher: Watcher |
|
168 | 169 | |
169 | 170 |
setting_app_title: Applikationstitel |
170 | 171 |
setting_app_subtitle: Applicationsunderrubrik |
lang/th.yml | ||
---|---|---|
180 | 180 |
field_searchable: ค้นหาได้ |
181 | 181 |
field_default_value: ค่าเริ่มต้น |
182 | 182 |
field_comments_sorting: แสดงความเห็น |
183 |
field_watcher: Watcher |
|
183 | 184 | |
184 | 185 |
setting_app_title: ชื่อโปรแกรม |
185 | 186 |
setting_app_subtitle: ชื่อโปรแกรมรอง |
lang/uk.yml | ||
---|---|---|
172 | 172 |
field_column_names: Колонки |
173 | 173 |
field_time_zone: Часовий пояс |
174 | 174 |
field_searchable: Вживається у пошуку |
175 |
field_watcher: Watcher |
|
175 | 176 | |
176 | 177 |
setting_app_title: Назва додатку |
177 | 178 |
setting_app_subtitle: Підзаголовок додатку |
lang/zh-tw.yml | ||
---|---|---|
182 | 182 |
field_searchable: 可用做搜尋條件 |
183 | 183 |
field_default_value: 預設值 |
184 | 184 |
field_comments_sorting: 註解排序 |
185 |
field_watcher: Watcher |
|
185 | 186 | |
186 | 187 |
setting_app_title: 標題 |
187 | 188 |
setting_app_subtitle: 副標題 |
lang/zh.yml | ||
---|---|---|
183 | 183 |
field_default_value: 默认值 |
184 | 184 |
field_comments_sorting: 显示注释 |
185 | 185 |
field_parent_title: 上级页面 |
186 |
field_watcher: Watcher |
|
186 | 187 | |
187 | 188 |
setting_app_title: 应用程序标题 |
188 | 189 |
setting_app_subtitle: 应用程序子标题 |
189 |
- |
lang/nl.yml | ||
---|---|---|
165 | 165 |
field_redirect_existing_links: Redirect existing links |
166 | 166 |
field_estimated_hours: Estimated time |
167 | 167 |
field_default_value: Default value |
168 |
field_watcher: Watcher |
|
168 | 169 | |
169 | 170 |
setting_app_title: Applicatie titel |
170 | 171 |
setting_app_subtitle: Applicatie ondertitel |
171 |
- |
app/models/query.rb | ||
---|---|---|
359 | 359 |
when "!~" |
360 | 360 |
sql = sql + "#{db_table}.#{db_field} NOT LIKE '%#{connection.quote_string(v.first)}%'" |
361 | 361 |
when "<w" |
362 |
sql = sql + "#{Issue.table_name}.id IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" if field == "watcher_id"
|
|
362 |
sql = sql + "#{db_table}.id IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" if field == "watcher_id"
|
|
363 | 363 |
when ">w" |
364 |
sql = sql + "#{Issue.table_name}.id IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id NOT IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" if field == "watcher_id"
|
|
364 |
sql = sql + "#{db_table}.id NOT IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))" if field == "watcher_id"
|
|
365 | 365 |
end |
366 | 366 |
sql << ')' |
367 | 367 |
filters_clauses << sql |
368 |
- |
test/unit/query_test.rb | ||
---|---|---|
123 | 123 |
find_issues_with_query(query) |
124 | 124 |
end |
125 | 125 |
|
126 |
def test_operator_equals_watcher |
|
127 |
query = Query.new(:project => Project.find(1), :name => '_') |
|
128 |
user = User.find(1) |
|
129 |
query.add_filter('watcher_id', '<w', [user.id.to_s]) |
|
130 |
assert query.statement.include?("#{Issue.table_name}.id IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id IN ('" + user.id.to_s + "'))") |
|
131 |
find_issues_with_query(query) |
|
132 |
end |
|
133 |
|
|
134 |
def test_operator_not_equals_watcher |
|
135 |
query = Query.new(:project => Project.find(1), :name => '_') |
|
136 |
user = User.find(1) |
|
137 |
query.add_filter('watcher_id', '>w', [user.id.to_s]) |
|
138 |
assert query.statement.include?("#{Issue.table_name}.id NOT IN (SELECT #{Watcher.table_name}.watchable_id FROM #{Watcher.table_name} WHERE #{Watcher.table_name}.watchable_type = 'Issue' AND #{Watcher.table_name}.user_id IN ('" + user.id.to_s + "'))") |
|
139 |
find_issues_with_query(query) |
|
140 |
end |
|
141 |
|
|
126 | 142 |
def test_default_columns |
127 | 143 |
q = Query.new |
128 | 144 |
assert !q.columns.empty? |