diff --git app/controllers/default_custom_query_setting_controller.rb app/controllers/default_custom_query_setting_controller.rb new file mode 100644 index 0000000..8b965a5 --- /dev/null +++ app/controllers/default_custom_query_setting_controller.rb @@ -0,0 +1,36 @@ +# Redmine - project management software +# Copyright (C) 2006-2015 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class DefaultCustomQuerySettingController < ApplicationController + before_filter :find_project_by_project_id + before_filter :authorize + + helper :default_custom_query + + def update + settings = params[:settings] + + @default_query = ProjectsDefaultQuery.initialize_for(@project.id) + @default_query.query_id = settings[:query_id] + + if @default_query.save + session[:query] = nil + end + + render partial: 'form' + end +end diff --git app/controllers/issues_controller.rb app/controllers/issues_controller.rb index 5199954..8a57fdd 100644 --- app/controllers/issues_controller.rb +++ app/controllers/issues_controller.rb @@ -24,6 +24,7 @@ class IssuesController < ApplicationController before_filter :authorize, :except => [:index, :new, :create] before_filter :find_optional_project, :only => [:index, :new, :create] before_filter :build_new_issue_from_params, :only => [:new, :create] + before_filter :with_default_query, only: [:index], if: :default_query_module_enabled? accept_rss_auth :index, :show accept_api_auth :index, :show, :create, :update, :destroy @@ -353,6 +354,38 @@ class IssuesController < ApplicationController private + def with_default_query + case + when params[:query_id].present? + # Nothing to do + when api_request? + # Nothing to do + # when show_all_issues? + when params[:without_default] + params[:set_filter] = 1 + # when filter_applied? + when params[:set_filter] && params.key?(:op) && params.key?(:f) + # Nothing to do + # when filter_cleared? + when params[:set_filter] && [:op, :f].all? {|k| !params.key?(k) } + apply_default_query! + when session[:query] + query_id, project_id = session[:query].values_at(:id, :project_id) + unless query_id && (project_id == @project.id) && IssueQuery.available_query?(@project.id, query_id) + apply_default_query! + end + else + apply_default_query! + end + end + + def apply_default_query! + default_query = find_default_query + if 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 app/controllers/projects_controller.rb app/controllers/projects_controller.rb index 7e1798a..c42b73c 100644 --- app/controllers/projects_controller.rb +++ app/controllers/projects_controller.rb @@ -38,6 +38,7 @@ class ProjectsController < ApplicationController helper :queries helper :repositories helper :members + helper :default_custom_query # Lists visible projects def index diff --git app/helpers/default_custom_query_helper.rb app/helpers/default_custom_query_helper.rb new file mode 100644 index 0000000..074250c --- /dev/null +++ app/helpers/default_custom_query_helper.rb @@ -0,0 +1,19 @@ +module DefaultCustomQueryHelper + def options_for_selectable_queries(project) + options_groups = [] + + queries = IssueQuery.only_public.where(project_id: nil) + if queries.any? + options_groups << [l('default_custom_query.label_queries_for_all_projects'), queries] + end + + queries = project.queries.only_public + if queries.any? + options_groups << [l('default_custom_query.label_queries_for_current_project'), queries] + end + + options_groups.map do |group, options| + [group, options.collect {|o| [o.name, o.id] }] + end + end +end \ No newline at end of file diff --git app/helpers/projects_helper.rb app/helpers/projects_helper.rb index 6e409f2..53cdce5 100644 --- app/helpers/projects_helper.rb +++ app/helpers/projects_helper.rb @@ -27,9 +27,10 @@ module ProjectsHelper {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki}, {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural}, {:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural}, - {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities} + {:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}, + {:name => 'default_custom_query', :action => :manage_default_query, :partial => 'default_custom_query_setting/form', :label => :'default_custom_query.label_setting'} ] - tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} + tabs = tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)} end def parent_project_select_tag(project) diff --git app/helpers/queries_helper.rb app/helpers/queries_helper.rb index 4b71d08..c163529 100644 --- app/helpers/queries_helper.rb +++ app/helpers/queries_helper.rb @@ -241,9 +241,21 @@ module QueriesHelper @query.project = @project end @query + else + @query = find_default_query end end + private + + def find_default_query + @project.default_query if @project.is_a?(Project) + end + + def default_query_module_enabled? + @project && @project.module_enabled?(:default_custom_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) diff --git app/models/issue_query.rb app/models/issue_query.rb index c97de0a..f98396d 100644 --- app/models/issue_query.rb +++ app/models/issue_query.rb @@ -16,6 +16,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class IssueQuery < Query + has_many :projects_default_queries, dependent: :nullify, foreign_key: :query_id self.queried_class = Issue @@ -71,6 +72,16 @@ class IssueQuery < Query end } + scope :only_public, -> { + where(:visibility => VISIBILITY_PUBLIC) + } + + def self.available_query?(project_id, query_id) + self.only_public + .where('project_id is null or project_id = ?', project_id) + .where(id: query_id).exists? + end + def initialize(attributes=nil, *args) super attributes self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} } @@ -102,6 +113,10 @@ class IssueQuery < Query !is_private? end + def public_visibility? + visibility == VISIBILITY_PUBLIC + end + def draw_relations r = options[:draw_relations] r.nil? || r == '1' diff --git app/models/project.rb app/models/project.rb index 2e3a106..d263f48 100644 --- app/models/project.rb +++ app/models/project.rb @@ -55,6 +55,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 Queries + has_many :default_queries, dependent: :delete_all, :class_name => 'ProjectsDefaultQuery' acts_as_attachable :view_permission => :view_files, :edit_permission => :manage_files, @@ -790,6 +792,14 @@ class Project < ActiveRecord::Base end end + def default_query + default_queries.first.try :query + end + + def init_default_query + default_queries.first || default_queries.new + end + private def update_inherited_members diff --git app/models/projects_default_query.rb app/models/projects_default_query.rb new file mode 100644 index 0000000..60d2a20 --- /dev/null +++ app/models/projects_default_query.rb @@ -0,0 +1,61 @@ +# Redmine - project management software +# Copyright (C) 2006-2015 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class ProjectsDefaultQuery < ActiveRecord::Base + belongs_to :project + belongs_to :query, class_name: 'IssueQuery' + + validates :project_id, :query_id, numericality: { allow_nil: true } + validates :project_id, uniqueness: true, presence: true + validate :query_must_be_selectable + + def self.initialize_for(project_id) + default_query = where(:project_id => project_id).first + + unless default_query + default_query = self.new + default_query.project_id = project_id + end + default_query + end + + def query + return unless super + + unless new_record? || selectable_query?(super) + update_attribute :query_id, nil + end + super + end + + private + + def query_must_be_selectable + return if errors.any? || query_id.blank? || !query_id_changed? + + issue_query = IssueQuery.where(:id => query_id).first + + unless selectable_query?(issue_query) + errors.add :query_id, :invalid + end + end + + def selectable_query?(query) + query && query.public_visibility? && + (query.project.nil? || query.project == project) + end +end diff --git app/views/default_custom_query_setting/_form.html.erb app/views/default_custom_query_setting/_form.html.erb new file mode 100644 index 0000000..cc8cc96 --- /dev/null +++ app/views/default_custom_query_setting/_form.html.erb @@ -0,0 +1,21 @@ +<%= labelled_form_for @default_query ||= @project.init_default_query, + as: :settings, + url: default_custom_query_setting_update_path(@project), + remote: true, method: :put, html: { id: 'default-query-setting' } do |f| %> + + <%= error_messages_for @default_query %> + +
+

+ <%= f.select :query_id, options_for_selectable_queries(@project), include_blank: true %>
+ <%=l 'default_custom_query.text_allowed_queries' %> +

+
+ <%= submit_tag l(:button_save) %> +<% end %> + + diff --git app/views/issues/_sidebar.html.erb app/views/issues/_sidebar.html.erb index df9f43b..82c1e34 100644 --- app/views/issues/_sidebar.html.erb +++ app/views/issues/_sidebar.html.erb @@ -1,7 +1,10 @@

<%= l(:label_issue_plural) %>