Feature #35795 » 0001-Option-to-set-default-project-query-at-global-and-us.patch
app/controllers/projects_controller.rb | ||
---|---|---|
51 | 51 |
return |
52 | 52 |
end |
53 | 53 | |
54 |
retrieve_default_query |
|
54 | 55 |
retrieve_project_query |
55 | 56 |
scope = project_scope |
56 | 57 | |
... | ... | |
323 | 324 |
def retrieve_project_query |
324 | 325 |
retrieve_query(ProjectQuery, false, :defaults => @default_columns_names) |
325 | 326 |
end |
327 | ||
328 |
def retrieve_default_query |
|
329 |
return if params[:query_id].present? |
|
330 |
return if api_request? |
|
331 |
return if params[:set_filter] && (params.key?(:op) || params.key?(:f)) |
|
332 | ||
333 |
if params[:without_default].present? |
|
334 |
params[:set_filter] = 1 |
|
335 |
return |
|
336 |
end |
|
337 | ||
338 |
if default_query = ProjectQuery.default |
|
339 |
params[:query_id] = default_query.id |
|
340 |
end |
|
341 |
end |
|
326 | 342 |
end |
app/helpers/settings_helper.rb | ||
---|---|---|
170 | 170 |
[[l(:label_none), '']] + IssueQuery.only_public.where(project_id: nil).pluck(:name, :id) |
171 | 171 |
end |
172 | 172 | |
173 |
def default_global_project_query_options |
|
174 |
[[l(:label_none), '']] + ProjectQuery.only_public.pluck(:name, :id) |
|
175 |
end |
|
176 | ||
173 | 177 |
def cross_project_subtasks_options |
174 | 178 |
options = [ |
175 | 179 |
[:label_disabled, ''], |
app/helpers/users_helper.rb | ||
---|---|---|
41 | 41 |
grouped_options_for_select(grouped, user.pref.default_issue_query) |
42 | 42 |
end |
43 | 43 | |
44 |
def default_project_query_options(user) |
|
45 |
global_queries = ProjectQuery |
|
46 |
global_public_queries = global_queries.only_public |
|
47 |
global_user_queries = global_queries.where(user_id: user.id).where.not(id: global_public_queries.ids) |
|
48 |
label = user == User.current ? 'label_my_queries' : 'label_default_queries.for_this_user' |
|
49 |
grouped = { |
|
50 |
l('label_default_queries.for_all_users') => global_public_queries.pluck(:name, :id), |
|
51 |
l(".#{label}") => global_user_queries.pluck(:name, :id), |
|
52 |
} |
|
53 |
grouped_options_for_select(grouped, user.pref.default_project_query) |
|
54 |
end |
|
55 | ||
44 | 56 |
def textarea_font_options |
45 | 57 |
[[l(:label_font_default), '']] + UserPreference::TEXTAREA_FONT_OPTIONS.map {|o| [l("label_font_#{o}"), o]} |
46 | 58 |
end |
app/models/issue_query.rb | ||
---|---|---|
75 | 75 | |
76 | 76 |
has_many :projects, foreign_key: 'default_issue_query_id', dependent: :nullify, inverse_of: 'default_issue_query' |
77 | 77 |
after_update { projects.clear unless visibility == VISIBILITY_PUBLIC } |
78 |
scope :only_public, ->{ where(visibility: VISIBILITY_PUBLIC) } |
|
79 | 78 |
scope :for_all_projects, ->{ where(project_id: nil) } |
80 | 79 | |
81 | 80 |
def self.default(project: nil, user: User.current) |
app/models/project_query.rb | ||
---|---|---|
37 | 37 |
QueryColumn.new(:created_on, :sortable => "#{Project.table_name}.created_on", :default_order => 'desc') |
38 | 38 |
] |
39 | 39 | |
40 |
def self.default(project: nil, user: User.current) |
|
41 |
query = nil |
|
42 |
if user&.logged? |
|
43 |
query = find_by_id user.pref.default_project_query |
|
44 |
end |
|
45 |
query || find_by_id(Setting.default_project_query) |
|
46 |
end |
|
47 | ||
40 | 48 |
def initialize(attributes=nil, *args) |
41 | 49 |
super attributes |
42 | 50 |
self.filters ||= {'status' => {:operator => "=", :values => ['1']}} |
app/models/query.rb | ||
---|---|---|
339 | 339 |
end) |
340 | 340 | |
341 | 341 |
scope :sorted, lambda {order(:name, :id)} |
342 |
scope :only_public, ->{ where(visibility: VISIBILITY_PUBLIC) } |
|
342 | 343 | |
343 | 344 |
# to be implemented in subclasses that have a way to determine a default |
344 | 345 |
# query for the given options |
app/models/user_preference.rb | ||
---|---|---|
38 | 38 |
'recently_used_projects', |
39 | 39 |
'history_default_tab', |
40 | 40 |
'default_issue_query', |
41 |
'default_project_query', |
|
41 | 42 |
'toolbar_language_options') |
42 | 43 | |
43 | 44 |
TEXTAREA_FONT_OPTIONS = ['monospace', 'proportional'] |
... | ... | |
120 | 121 |
def default_issue_query; self[:default_issue_query] end |
121 | 122 |
def default_issue_query=(value); self[:default_issue_query]=value; end |
122 | 123 | |
124 |
def default_project_query; self[:default_project_query] end |
|
125 |
def default_project_query=(value); self[:default_project_query]=value; end |
|
126 | ||
123 | 127 |
# Returns the names of groups that are displayed on user's page |
124 | 128 |
# Example: |
125 | 129 |
# preferences.my_page_groups |
app/views/settings/_projects.html.erb | ||
---|---|---|
28 | 28 |
</p> |
29 | 29 |
<%= render_query_columns_selection(query, |
30 | 30 |
:name => 'settings[project_list_defaults][column_names]') %> |
31 | ||
32 |
<p><%= setting_select :default_project_query, default_global_project_query_options %></p> |
|
31 | 33 |
</fieldset> |
32 | 34 | |
33 | 35 |
app/views/users/_preferences.html.erb | ||
---|---|---|
8 | 8 |
<p><%= pref_fields.select :history_default_tab, history_default_tab_options %></p> |
9 | 9 |
<p><%= pref_fields.text_area :toolbar_language_options, :rows => 4 %></p> |
10 | 10 |
<p><%= pref_fields.select :default_issue_query, default_issue_query_options(@user), include_blank: l(:label_none) %></p> |
11 |
<p><%= pref_fields.select :default_project_query, default_project_query_options(@user), include_blank: l(:label_none) %></p> |
|
11 | 12 |
<% end %> |
config/locales/en.yml | ||
---|---|---|
510 | 510 |
setting_project_list_defaults: Projects list defaults |
511 | 511 |
setting_twofa: Two-factor authentication |
512 | 512 |
setting_default_issue_query: Default Query |
513 |
setting_default_project_query: Default Query |
|
513 | 514 | |
514 | 515 |
permission_add_project: Create project |
515 | 516 |
permission_add_subprojects: Create subprojects |
config/settings.yml | ||
---|---|---|
249 | 249 |
- name |
250 | 250 |
- identifier |
251 | 251 |
- short_description |
252 |
default_project_query: |
|
253 |
default: '' |
|
252 | 254 |
issue_done_ratio: |
253 | 255 |
default: 'issue_field' |
254 | 256 |
default_projects_public: |
test/fixtures/queries.yml | ||
---|---|---|
182 | 182 |
--- |
183 | 183 |
- - spent_on |
184 | 184 |
- desc |
185 |
queries_011: |
|
186 |
id: 11 |
|
187 |
type: ProjectQuery |
|
188 |
visibility: 2 |
|
189 |
name: Projects as list |
|
190 |
filters: | |
|
191 |
--- |
|
192 |
id: |
|
193 |
:values: |
|
194 |
- "mine" |
|
195 |
:operator: = |
|
185 | 196 | |
197 |
column_names: |
|
198 |
group_by: |
|
199 |
sort_criteria: |
|
200 |
options: | |
|
201 |
--- |
|
202 |
:display_type: list |
|
203 |
queries_012: |
|
204 |
id: 12 |
|
205 |
type: ProjectQuery |
|
206 |
visibility: 1 |
|
207 |
name: My bookmarks |
|
208 |
filters: | |
|
209 |
--- |
|
210 |
id: |
|
211 |
:values: |
|
212 |
- "bookmarks" |
|
213 |
:operator: = |
|
214 | ||
215 |
user_id: 1 |
|
216 |
options: | |
|
217 |
--- |
|
218 |
:display_type: board |
test/functional/projects_controller_test.rb | ||
---|---|---|
25 | 25 |
:trackers, :projects_trackers, :issue_statuses, |
26 | 26 |
:enabled_modules, :enumerations, :boards, :messages, |
27 | 27 |
:attachments, :custom_fields, :custom_values, :time_entries, |
28 |
:wikis, :wiki_pages, :wiki_contents, :wiki_content_versions |
|
28 |
:wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, |
|
29 |
:roles, :queries |
|
29 | 30 | |
30 | 31 |
include Redmine::I18n |
31 | 32 | |
... | ... | |
248 | 249 |
assert_select ".total-for-cf-#{field.id} span.value", :text => '9' |
249 | 250 |
end |
250 | 251 | |
252 |
def test_index_should_retrieve_default_query |
|
253 |
query = ProjectQuery.find(11) |
|
254 |
ProjectQuery.stubs(:default).returns query |
|
255 | ||
256 |
[nil, 1].each do |user_id| |
|
257 |
@request.session[:user_id] = user_id |
|
258 |
get :index |
|
259 |
assert_select 'h2', text: query.name |
|
260 |
end |
|
261 |
end |
|
262 | ||
263 |
def test_index_should_ignore_default_query_with_without_default |
|
264 |
query = ProjectQuery.find(11) |
|
265 |
ProjectQuery.stubs(:default).returns query |
|
266 | ||
267 |
[nil, 1].each do |user_id| |
|
268 |
@request.session[:user_id] = user_id |
|
269 |
get :index, params: { set_filter: '1', without_default: '1' } |
|
270 |
assert_select 'h2', text: I18n.t(:label_project_plural) |
|
271 |
end |
|
272 |
end |
|
273 | ||
251 | 274 |
def test_autocomplete_js |
252 | 275 |
get( |
253 | 276 |
:autocomplete, |
test/integration/api_test/projects_test.rb | ||
---|---|---|
22 | 22 |
class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base |
23 | 23 |
fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details, |
24 | 24 |
:trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, |
25 |
:attachments, :custom_fields, :custom_values, :custom_fields_projects, :time_entries, :issue_categories |
|
25 |
:attachments, :custom_fields, :custom_values, :custom_fields_projects, :time_entries, :issue_categories, |
|
26 |
:queries |
|
26 | 27 | |
27 | 28 |
def setup |
28 | 29 |
super |
... | ... | |
212 | 213 |
assert_equal version.name, json['project']['default_version']['name'] |
213 | 214 |
end |
214 | 215 | |
216 |
def test_get_project_should_not_load_default_query |
|
217 |
query = ProjectQuery.find(11) |
|
218 |
ProjectQuery.stubs(:default).returns query |
|
219 | ||
220 |
get '/projects.json' |
|
221 | ||
222 |
assert results = JSON.parse(@response.body)['projects'] |
|
223 | ||
224 |
assert_equal 4, results.count |
|
225 |
assert results.detect{ |i| i['name'] == "eCookbook"} |
|
226 |
end |
|
227 | ||
215 | 228 |
test "POST /projects.xml with valid parameters should create the project" do |
216 | 229 |
with_settings :default_projects_modules => ['issue_tracking', 'repository'] do |
217 | 230 |
assert_difference('Project.count') do |
test/unit/project_query_test.rb | ||
---|---|---|
25 | 25 |
:issue_categories, :enumerations, |
26 | 26 |
:groups_users, |
27 | 27 |
:enabled_modules, |
28 |
:custom_fields, :custom_values |
|
28 |
:custom_fields, :custom_values, |
|
29 |
:queries |
|
29 | 30 | |
30 | 31 |
include Redmine::I18n |
31 | 32 | |
... | ... | |
69 | 70 |
end |
70 | 71 |
end |
71 | 72 |
end |
73 | ||
74 |
def test_should_determine_default_project_query |
|
75 |
user = User.find(1) |
|
76 |
query = ProjectQuery.find(11) |
|
77 |
user_query = ProjectQuery.find(12) |
|
78 | ||
79 |
[nil, user, User.anonymous].each do |u| |
|
80 |
assert_nil IssueQuery.default(user: u) |
|
81 |
end |
|
82 | ||
83 |
# only global default is set |
|
84 |
with_settings :default_project_query => query.id do |
|
85 |
[nil, user, User.anonymous].each do |u| |
|
86 |
assert_equal query, ProjectQuery.default(user: u) |
|
87 |
end |
|
88 |
end |
|
89 | ||
90 |
# user default, overrides global default |
|
91 |
user.pref.default_project_query = user_query.id |
|
92 |
user.pref.save |
|
93 | ||
94 |
with_settings :default_project_query => query.id do |
|
95 |
assert_equal user_query, ProjectQuery.default(user: user) |
|
96 |
end |
|
97 |
end |
|
98 | ||
99 |
def test_project_query_default_should_return_nil_if_default_query_destroyed |
|
100 |
query = ProjectQuery.find(11) |
|
101 | ||
102 |
Setting.default_project_query = query.id |
|
103 |
query.destroy |
|
104 | ||
105 |
assert_nil ProjectQuery.default |
|
106 |
end |
|
72 | 107 |
end |