diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index e2cc1505e..65d8e8ff7 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -25,6 +25,7 @@ class IssuesController < ApplicationController before_action :authorize, :except => [:index, :new, :create] before_action :find_optional_project, :only => [:index, :new, :create] before_action :build_new_issue_from_params, :only => [:new, :create] + before_action :with_default_query, only: [:index] accept_rss_auth :index, :show accept_api_auth :index, :show, :create, :update, :destroy @@ -468,6 +469,28 @@ class IssuesController < ApplicationController private + def with_default_query + return if params[:query_id].present? + return if api_request? + return if params[:set_filter] && params.key?(:op) && params.key?(:f) + params[:set_filter] = 1 and return if params[:without_default].present? + apply_default_query! and return if params[:set_filter] && [:op, :f].all? { |k| !params.key?(k) } + if session[:issue_query] + query_id, project_id = session[:issue_query].values_at(:id, :project_id) + unless query_id && (@project.is_a?(Project) && project_id == @project.id) && IssueQuery.available_query?(@project.id, query_id, User.current.id) + apply_default_query! + end + else + apply_default_query! + end + end + + def apply_default_query! + if default_query = find_default_query + params[:query_id] = default_query.id + end + end + def retrieve_previous_and_next_issue_ids if params[:prev_issue_id].present? || params[:next_issue_id].present? @prev_issue_id = params[:prev_issue_id].presence.try(:to_i) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 785f84291..010e1b8e3 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -110,6 +110,17 @@ module ProjectsHelper principals_options_for_select(assignable_users, project.default_assigned_to) end + def project_default_query_options(project) + grouped = Hash.new {|h,k| h[k] = []} + IssueQuery.only_public.where(project_id: nil).each do |query| + grouped[l('label_default_queries.for_all_projects')] << [query.name, query.id] + end + IssueQuery.only_public.where(project: project).each do |query| + grouped[l('label_default_queries.for_current_project')] << [query.name, query.id] + end + grouped_options_for_select(grouped, project.default_query_id) + end + def format_version_sharing(sharing) sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing) l("label_version_sharing_#{sharing}") diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index a9d8cff6f..bee523471 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -347,9 +347,29 @@ module QueriesHelper @query.project = @project end @query + else + @query = find_default_query end end + private + + def find_default_query + query = nil + if User.current.pref.default_user_project_query != nil + query = IssueQuery.find_by_id(User.current.pref.default_user_project_query) + end + + unless query.is_a?(IssueQuery) + if @project.is_a?(Project) and @project.default_query.is_a?(IssueQuery) + query = @project.default_query + elsif Setting.default_project_query != nil + query = IssueQuery.find_by_id(Setting.default_project_query) + end + end + query + end + # Returns the query definition as hidden field tags def query_as_hidden_field_tags(query) tags = hidden_field_tag("set_filter", "1", :id => nil) @@ -408,9 +428,16 @@ module QueriesHelper queries.collect {|query| css = +'query' clear_link = +'' + clear_link_param = {:set_filter => 1, :sort => '', :project_id => @project} + + if query == find_default_query + css << ' default' + clear_link_param[:without_default] = 1 + end + if query == @query css << ' selected' - clear_link += link_to_clear_query + clear_link += link_to_clear_query(clear_link_param) end content_tag('li', link_to(query.name, @@ -422,10 +449,10 @@ module QueriesHelper ) + "\n" end - def link_to_clear_query + def link_to_clear_query(params = {:set_filter => 1, :sort => '', :project_id => @project}) link_to( l(:button_clear), - {:set_filter => 1, :sort => '', :project_id => @project}, + params, :class => 'icon-only icon-clear-query', :title => l(:button_clear) ) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 8d8d98d72..18b2768b3 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -165,6 +165,16 @@ module SettingsHelper options.map {|label, value| [l(label), value.to_s]} end + def default_global_project_query_options + options = [ + [l(:label_none), ''] + ] + IssueQuery.only_public.where(project_id: nil).each do |query| + options.push([query.name, query.id]) + end + options + end + def cross_project_subtasks_options options = [ [:label_disabled, ''], diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 1f5841199..ccbd14760 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -29,6 +29,17 @@ module UsersHelper user.valid_notification_options.collect {|o| [l(o.last), o.first]} end + def default_user_project_query_options(user) + grouped = Hash.new {|h,k| h[k] = []} + IssueQuery.only_public.for_all_projects.each do |query| + grouped[l('label_default_queries.for_all_users')] << [query.name, query.id] + end + IssueQuery.for_all_projects.where(user_id: user.id).each do |query| + grouped[l('label_default_queries.for_current_user')] << [query.name, query.id] + end + grouped_options_for_select(grouped, user.pref.default_user_project_query) + end + def textarea_font_options [[l(:label_font_default), '']] + UserPreference::TEXTAREA_FONT_OPTIONS.map {|o| [l("label_font_#{o}"), o]} end diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 79905b11a..0d4317680 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -55,11 +55,31 @@ class IssueQuery < Query QueryColumn.new(:last_notes, :caption => :label_last_notes, :inline => false) ] + has_many :projects, :foreign_key => 'default_query_id' + after_update { self.projects.clear unless self.public_visibility? } + after_destroy { self.projects.clear } + scope :only_public, -> { + where(:visibility => VISIBILITY_PUBLIC) + } + scope :for_all_projects, -> { + where(project_id: nil) + } + + def self.available_query?(project_id, query_id, user_id) + self.where('project_id is null or project_id = ?', project_id) + .where('user_id = ? or visibility = ?', user_id, VISIBILITY_PUBLIC) + .where(id: query_id).exists? + end + def initialize(attributes=nil, *args) super attributes self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} } end + def public_visibility? + visibility == VISIBILITY_PUBLIC + end + def draw_relations r = options[:draw_relations] r.nil? || r == '1' diff --git a/app/models/project.rb b/app/models/project.rb index 0119b1228..7920e62dd 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -58,6 +58,8 @@ class Project < ActiveRecord::Base :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :association_foreign_key => 'custom_field_id' + # Default Custom Query + belongs_to :default_query, :class_name => 'IssueQuery' acts_as_attachable :view_permission => :view_files, :edit_permission => :manage_files, @@ -767,7 +769,8 @@ class Project < ActiveRecord::Base 'issue_custom_field_ids', 'parent_id', 'default_version_id', - 'default_assigned_to_id') + 'default_assigned_to_id', + 'default_query_id') safe_attributes( 'enabled_module_names', diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index 2a0efb7f9..5ec6e0c91 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -37,6 +37,7 @@ class UserPreference < ActiveRecord::Base 'textarea_font', 'recently_used_projects', 'history_default_tab', + 'default_user_project_query', 'toolbar_language_options') TEXTAREA_FONT_OPTIONS = ['monospace', 'proportional'] @@ -113,6 +114,9 @@ class UserPreference < ActiveRecord::Base self[:toolbar_language_options] = languages.join(',') end + def default_user_project_query; self[:default_user_project_query] end + def default_user_project_query=(value); self[:default_user_project_query]=value; end + # Returns the names of groups that are displayed on user's page # Example: # preferences.my_page_groups diff --git a/app/views/projects/copy.html.erb b/app/views/projects/copy.html.erb index 8a7805ef0..d1a7c9d9b 100644 --- a/app/views/projects/copy.html.erb +++ b/app/views/projects/copy.html.erb @@ -28,3 +28,13 @@ <%= submit_tag l(:button_copy) %> <% end %> + +<%= javascript_tag do %> + $('input[value="queries"]').change(function() { + if ($(this).prop('checked')){ + $('select#project_default_query_id optgroup[label="For current project"] option').prop("disabled", false); + }else{ + $('select#project_default_query_id optgroup[label="For current project"] option').prop("disabled", true); + } + }); +<% end %> \ No newline at end of file diff --git a/app/views/projects/settings/_issues.html.erb b/app/views/projects/settings/_issues.html.erb index 5b2db2937..04d8e3ec4 100644 --- a/app/views/projects/settings/_issues.html.erb +++ b/app/views/projects/settings/_issues.html.erb @@ -41,6 +41,13 @@ <% if @project.safe_attribute?('default_assigned_to_id') %>
<%= f.select :default_assigned_to_id, project_default_assigned_to_options(@project), include_blank: l(:label_none) %>
<% end %> + + <% if @project.safe_attribute?('default_query_id') && project_default_query_options(@project).present? %> ++ <%= f.select :default_query_id, project_default_query_options(@project), include_blank: l(:label_none) %> + <%=l 'text_allowed_queries_to_select' %> +
+ <% end %><%= submit_tag l(:button_save) %>
diff --git a/app/views/settings/_issues.html.erb b/app/views/settings/_issues.html.erb index b4e50d8e3..6d4c2a512 100644 --- a/app/views/settings/_issues.html.erb +++ b/app/views/settings/_issues.html.erb @@ -24,6 +24,8 @@<%= setting_text_field :gantt_items_limit, :size => 6 %>
<%= setting_text_field :gantt_months_limit, :size => 6 %>
+ +<%= setting_select :default_project_query, default_global_project_query_options %>