diff --git a/app/controller/subject_autocomplete_controller.rb b/app/controller/subject_autocomplete_controller.rb index e3adec5..8abc2ec 100644 --- a/app/controller/subject_autocomplete_controller.rb +++ b/app/controller/subject_autocomplete_controller.rb @@ -1,64 +1,52 @@ # -*- coding: utf-8 -*- class SubjectAutocompleteController < ApplicationController - - if Rails::VERSION::MAJOR >= 4 - before_action :find_project, :init - else - before_filter :find_project, :init - end - - def init - @issue_status_closed = IssueStatus.where('is_closed=?', true).pluck :id - @issue_status_open = IssueStatus.select('id').where('is_closed=?', false).pluck :id - end + before_action :find_project, only: :get_matches def get_matches # autocomplete for the issue subject field. limit_count = 15 default_closed_past_days = 30 + # load closed tickets, show issue id @issues = [] q = params[:term].to_s.strip if q.present? - if @project.nil? - scope = Issue.visible - else - if @project.parent - project_siblings = Project.where(:parent_id => @project.parent.id).map{|e| e.id } - project_siblings_children = Project.where(:parent_id => project_siblings).map{|e| e.id } - projects = project_siblings + project_siblings_children << @project.parent[:id] - else - project_children = Project.where(:parent_id => @project.id).map{|e| e.id } - projects = project_children << @project.id - end - scope = Issue.where(:project_id => projects).visible + scope = Issue.joins(:status, :project).visible + + if @project.present? + scope = scope.where(@project.project_condition(true)) end - if q.match(/\A#?(\d+)\z/) - @issues << scope.find_by_id($1.to_i) + + if q =~ /\A#?(\d+)\z/ + @issues << scope.find_by(id: ::Regexp.last_match(1).to_i) end past_days = params[:closed_past_days] ? params[:closed_past_days].to_i : default_closed_past_days - time_now = DateTime.now - # use ruby regexp. not all databases support regexp in sql - q = q.gsub(/[^a-zA-Z0-9# ]/, "").split(" ").map{|e| - e = Issue.connection.quote("%#{e}%") - "lower(#{Issue.table_name}.subject) like #{e}"}.join(" and ") + + open_or_closed_in_past_days = + scope + .where({ issue_statuses: { is_closed: true } }) + .where( + Issue.sanitize_sql_for_assignment(["issues.updated_on between ? and ?", past_days.days.ago, Time.current]) + ).or(scope.open) + @issues += scope - .where("#{q} and " + - "(issues.status_id in(?) or (issues.status_id in(?) and issues.updated_on between ? and ?))", - @issue_status_open, @issue_status_closed, time_now - past_days, time_now) + .like(q) + .and(open_or_closed_in_past_days) .order("#{Issue.table_name}.id desc") .limit(limit_count) @issues.compact! versions = {} Version.select("id,name").each{|e| versions[e.id] = e.name } end + render :json => @issues.map {|e| label = "##{e[:id]} #{e[:subject]}" if e.fixed_version_id then label = "#{versions[e.fixed_version_id]} » #{label}" end + { "label" => label, "value" => "", - "issue_url" => url_for(:controller => "issues", :action => "show", :id => e[:id]), + "issue_url" => issue_path(e), "is_closed" => e.closed? } } @@ -67,9 +55,9 @@ def get_matches private def find_project - if params[:project_id].present? - @project = Project.find(params[:project_id]) - end + return if params[:project_id].blank? + + @project = Project.find(params[:project_id]) rescue ActiveRecord::RecordNotFound render_404 end diff --git a/config/locales/ru.yml b/config/locales/ru.yml new file mode 100644 index 0000000..c3f8200 --- /dev/null +++ b/config/locales/ru.yml @@ -0,0 +1,2 @@ +ru: + placeholder_text: "Тема / Поиск по существующим задачам" \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 8cccd36..f20c1dd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1 +1 @@ -get "sbject_autocomplete/:action", controller: "subject_autocomplete" +get "subject_autocomplete/get_matches", controller: "subject_autocomplete" diff --git a/lib/redmine_subject_autocomplete/hooks.rb b/lib/redmine_subject_autocomplete/hooks.rb index 1d2ca74..1c4cf30 100644 --- a/lib/redmine_subject_autocomplete/hooks.rb +++ b/lib/redmine_subject_autocomplete/hooks.rb @@ -3,7 +3,7 @@ module RedmineSubjectAutocomplete class Hooks < Redmine::Hook::ViewListener def view_issues_form_details_bottom(context) - path = (config.relative_url_root || '') + url_for({controller: 'subject_autocomplete', action: 'get_matches'}) + "?project_id=#{context[:project][:id]}" + path = url_for({controller: 'subject_autocomplete', action: 'get_matches', project_id: context.try(:[], :project).try(:[], :id)}) translations = { "placeholder_text" => I18n.translate(:placeholder_text) }