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 |