diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 5e413ed611..22a2ecbffe 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -344,7 +344,7 @@ function observeParentIssueField(url) { updateElement: function(value) { document.getElementById('issue_parent_id').value = value.id; }, - parameters: 'scope=all' + parameters: 'scope=relatable' }); } @@ -358,7 +358,7 @@ function observeWorkPackageParentField(url) { updateElement: function(value) { document.getElementById('work_package_parent_id').value = value.id; }, - parameters: 'scope=all' + parameters: 'scope=relatable' }); } @@ -372,7 +372,7 @@ function observeRelatedIssueField(url) { updateElement: function(value) { document.getElementById('relation_to_id').value = value.id; }, - parameters: 'scope=all' + parameters: 'scope=relatable' }); } diff --git a/app/assets/stylesheets/content/_in_place_editing.lsg b/app/assets/stylesheets/content/_in_place_editing.lsg index f112d95246..74dc2078de 100644 --- a/app/assets/stylesheets/content/_in_place_editing.lsg +++ b/app/assets/stylesheets/content/_in_place_editing.lsg @@ -122,7 +122,7 @@
-
diff --git a/app/controllers/work_packages/auto_completes_controller.rb b/app/controllers/work_packages/auto_completes_controller.rb index 0e1303faa5..8b97289a58 100644 --- a/app/controllers/work_packages/auto_completes_controller.rb +++ b/app/controllers/work_packages/auto_completes_controller.rb @@ -30,43 +30,65 @@ require 'rack/utils' class WorkPackages::AutoCompletesController < ApplicationController - before_filter :find_project - def index - @work_packages = [] - q = params[:q].to_s + scope = determine_scope + if scope.nil? + render_404 + return + end - if q.present? - query = (params[:scope] == 'all' && Setting.cross_project_work_package_relations?) ? WorkPackage : @project.work_packages + query_term = params[:q].to_s + @work_packages = [] + # query for exact ID matches first, to make an exact match the first result of autocompletion + if query_term =~ /\A\d+\z/ + @work_packages |= scope.visible.find_all_by_id(query_term.to_i) + end - @work_packages |= query.visible.find_all_by_id(q.to_i) if q =~ /\A\d+\z/ + sql_query = ["LOWER(#{WorkPackage.table_name}.subject) LIKE :q OR + CAST(#{WorkPackage.table_name}.id AS CHAR(13)) LIKE :q", + { q: "%#{query_term.downcase}%" }] - @work_packages |= query.visible.find(:all, - limit: 10, - order: "#{WorkPackage.table_name}.id ASC", - conditions: ["LOWER(#{WorkPackage.table_name}.subject) LIKE :q OR CAST(#{WorkPackage.table_name}.id AS CHAR(13)) LIKE :q", { q: "%#{q.downcase}%" }]) - end + @work_packages |= scope.visible + .where(sql_query) + .order("#{WorkPackage.table_name}.id ASC") # :id does not work because... + .limit(10) respond_to do |format| format.html { render layout: false } - format.any(:xml, :json) { render request.format.to_sym => wp_hash_with_string } + format.any(:xml, :json) { render request.format.to_sym => wp_hashes_with_string } end end private - def wp_hash_with_string - @work_packages.map do |wp| - Hash[wp.attributes.map do |key, value| - [key, Rack::Utils.escape_html(value)] - end << ['to_s', Rack::Utils.escape_html(wp.to_s)]] + def wp_hashes_with_string + @work_packages.map do |work_package| + wp_hash = Hash.new + work_package.attributes.each { |key, value| wp_hash[key] = Rack::Utils.escape_html(value) } + wp_hash['to_s'] = Rack::Utils.escape_html(work_package.to_s) + wp_hash end end def find_project project_id = (params[:work_package] && params[:work_package][:project_id]) || params[:project_id] - @project = Project.find(project_id) + return nil unless project_id + Project.find(project_id) rescue ActiveRecord::RecordNotFound - render_404 + nil + end + + def determine_scope + project = find_project + + if params[:scope] == 'relatable' + return nil unless project + + Setting.cross_project_work_package_relations? ? WorkPackage.scoped : project.work_packages + elsif params[:scope] == 'all' || project.nil? + WorkPackage.scoped + else + project.work_packages + end end end diff --git a/app/views/journals/_notes_form.html.erb b/app/views/journals/_notes_form.html.erb index c85190cce6..0ecc10590b 100644 --- a/app/views/journals/_notes_form.html.erb +++ b/app/views/journals/_notes_form.html.erb @@ -35,8 +35,7 @@ See doc/COPYRIGHT.rdoc for more details. <% rows = @journal.notes.blank? ? 10 : [[10, @journal.notes.length / 50].max, 100].min %> <%= text_area_tag :notes, @journal.notes, :class => 'wiki-edit', - :rows => rows, - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json) %> + :rows => rows %> <%= javascript_tag("enable_textarea_auto_completion(jQuery('#notes'));") %> <%= call_hook(:view_journals_notes_form_after_notes, { :journal => @journal}) %> diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb index fbbf814ad5..9f45e63e5b 100644 --- a/app/views/messages/_form.html.erb +++ b/app/views/messages/_form.html.erb @@ -45,7 +45,7 @@ See doc/COPYRIGHT.rdoc for more details. <% end %>
- <%= f.text_area :content, required: true, label: l(:description_message_content), class: 'wiki-edit', data: {:'ng-non-bindable' => '' }, 'data-wp_autocomplete_url' => work_packages_auto_complete_path(project_id: @project, format: :json) %> + <%= f.text_area :content, required: true, label: l(:description_message_content), class: 'wiki-edit', data: {:'ng-non-bindable' => '' } %> <%= wikitoolbar_for(replying ? 'reply_content' : 'message_content') %>
<%= render :partial => 'attachments/form' %> diff --git a/app/views/news/_form.html.erb b/app/views/news/_form.html.erb index 30119a8cc6..7a2c14623f 100644 --- a/app/views/news/_form.html.erb +++ b/app/views/news/_form.html.erb @@ -35,7 +35,6 @@ See doc/COPYRIGHT.rdoc for more details.
<%= f.text_area :description, :required => true, :cols => 60, :rows => 15, :class => 'wiki-edit', - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json), :'ng-non-bindable' => '' %>
<%= wikitoolbar_for 'news_description' %> diff --git a/app/views/news/show.html.erb b/app/views/news/show.html.erb index fc8a0c40a2..a370740790 100644 --- a/app/views/news/show.html.erb +++ b/app/views/news/show.html.erb @@ -95,8 +95,7 @@ See doc/COPYRIGHT.rdoc for more details. <%= form_for([@news, Comment.new], :html => { :id => "add_comment_form", :style => "display:none;" }) do %>
<%= label_tag 'comment_comments', Journal.human_attribute_name(:notes), :class => 'hidden-for-sighted' %> - <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit', - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json) %> + <%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> <%= wikitoolbar_for 'comment_comments' %>

<%= submit_tag l(:button_add), class: 'button -highlight' %>

diff --git a/app/views/project_associations/_form.html.erb b/app/views/project_associations/_form.html.erb index 5650106d53..90c99c1119 100644 --- a/app/views/project_associations/_form.html.erb +++ b/app/views/project_associations/_form.html.erb @@ -28,7 +28,6 @@ See doc/COPYRIGHT.rdoc for more details. ++#%>
<%= f.text_area(:description, :class => 'timelines-project-association-description wiki-edit', :rows => 10, - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json), :'ng-non-bindable' => '') %>
<%= wikitoolbar_for 'project_association_description' %> diff --git a/app/views/projects/form/attributes/_description.html.erb b/app/views/projects/form/attributes/_description.html.erb index 6b0572839f..f40b4bbfa1 100644 --- a/app/views/projects/form/attributes/_description.html.erb +++ b/app/views/projects/form/attributes/_description.html.erb @@ -27,17 +27,10 @@ See doc/COPYRIGHT.rdoc for more details. ++#%> -<% - project = form.object - autocomplete_path = work_packages_auto_complete_path(project_id: project, - format: :json) -%> -
<%= form.text_area :description, rows: 5, class: 'wiki-edit', - :'data-wp_autocomplete_url' => autocomplete_path, :'ng-non-bindable' => '' %>
<%= wikitoolbar_for 'project_description' %> diff --git a/app/views/projects/form/attributes/_summary.html.erb b/app/views/projects/form/attributes/_summary.html.erb index 0d40be2f4b..737b79ac5e 100644 --- a/app/views/projects/form/attributes/_summary.html.erb +++ b/app/views/projects/form/attributes/_summary.html.erb @@ -27,17 +27,9 @@ See doc/COPYRIGHT.rdoc for more details. ++#%> -<% - project = form.object - autocomplete_path = work_packages_auto_complete_path(project_id: project, - format: :json) -%> - -
<%= form.text_area :summary, rows: 2, class: 'wiki-edit', - :'data-wp_autocomplete_url' => autocomplete_path, :'ng-non-bindable' => '' %>
diff --git a/app/views/reportings/edit.html.erb b/app/views/reportings/edit.html.erb index 4ca696cedf..1b2628f618 100644 --- a/app/views/reportings/edit.html.erb +++ b/app/views/reportings/edit.html.erb @@ -58,7 +58,6 @@ See doc/COPYRIGHT.rdoc for more details.
<%= f.text_area(:reported_project_status_comment, :class => 'wiki-edit', :rows => 10, - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json), :'ng-non-bindable' => '', label: Reporting.human_attribute_name(:reported_project_status_comment)) %>
<%= wikitoolbar_for 'reporting_reported_project_status_comment' %> diff --git a/app/views/wiki/edit.html.erb b/app/views/wiki/edit.html.erb index 58cf5b6845..d65a2643ed 100644 --- a/app/views/wiki/edit.html.erb +++ b/app/views/wiki/edit.html.erb @@ -33,7 +33,6 @@ See doc/COPYRIGHT.rdoc for more details.
<%= f.text_area :text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit), :value => format_text(@content, :text, :attachments => @content.page.attachments, :edit => true), - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json), :'ng-non-bindable' => '' %>
diff --git a/app/views/wiki/new.html.erb b/app/views/wiki/new.html.erb index f4223be123..2905caa230 100644 --- a/app/views/wiki/new.html.erb +++ b/app/views/wiki/new.html.erb @@ -49,7 +49,6 @@ See doc/COPYRIGHT.rdoc for more details.
<%= f.text_area :text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit), - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json), :'ng-non-bindable' => '' %>
diff --git a/app/views/work_packages/_edit.html.erb b/app/views/work_packages/_edit.html.erb index 12dc1ee40a..454b33bb57 100644 --- a/app/views/work_packages/_edit.html.erb +++ b/app/views/work_packages/_edit.html.erb @@ -57,8 +57,7 @@ See doc/COPYRIGHT.rdoc for more details. <%= f.text_area :journal_notes, :cols => 60, :rows => 10, :class => 'wiki-edit', - :label => Journal.human_attribute_name(:notes), - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => project, :format => :json) %> + :label => Journal.human_attribute_name(:notes) %> <%= wikitoolbar_for 'work_package_journal_notes' %> diff --git a/app/views/work_packages/_form.html.erb b/app/views/work_packages/_form.html.erb index ff9f976ee3..d7e82607de 100644 --- a/app/views/work_packages/_form.html.erb +++ b/app/views/work_packages/_form.html.erb @@ -57,8 +57,7 @@ See doc/COPYRIGHT.rdoc for more details. <%= f.text_field :subject, required: true %>
- <%= f.text_area :description, accesskey: accesskey(:edit), class: 'wiki-edit', rows: 10, :'ng-non-bindable' => '', - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(project_id: work_package.project, format: :json) %> + <%= f.text_area :description, accesskey: accesskey(:edit), class: 'wiki-edit', rows: 10, :'ng-non-bindable' => '' %>
diff --git a/app/views/work_packages/bulk/edit.html.erb b/app/views/work_packages/bulk/edit.html.erb index d229dc106c..48719771d4 100644 --- a/app/views/work_packages/bulk/edit.html.erb +++ b/app/views/work_packages/bulk/edit.html.erb @@ -140,8 +140,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= Journal.human_attribute_name(:notes) %> <%= label_tag 'notes', Journal.human_attribute_name(:notes), :class => 'hidden-for-sighted' %> - <%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit', - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @project, :format => :json) %> + <%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %> <%= wikitoolbar_for 'notes' %>

<%= send_notification_option %>

diff --git a/app/views/work_packages/moves/new.html.erb b/app/views/work_packages/moves/new.html.erb index 970b85244b..597a0ef341 100644 --- a/app/views/work_packages/moves/new.html.erb +++ b/app/views/work_packages/moves/new.html.erb @@ -113,8 +113,7 @@ See doc/COPYRIGHT.rdoc for more details.
<%= Journal.human_attribute_name(:notes) %> <%= label_tag 'notes', Journal.human_attribute_name(:notes), :class => 'hidden-for-sighted' %> - <%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit', - :'data-wp_autocomplete_url' => work_packages_auto_complete_path(:project_id => @target_project, :format => :json) %> + <%= styled_text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %> <%= wikitoolbar_for 'notes' %>
<%= call_hook(:view_work_packages_move_bottom, :work_packages => @work_packages, :target_project => @target_project, :copy => !!@copy) %> diff --git a/frontend/app/helpers/auto-complete-helper.js b/frontend/app/helpers/auto-complete-helper.js index cb1addf7b4..5def8b4b3e 100644 --- a/frontend/app/helpers/auto-complete-helper.js +++ b/frontend/app/helpers/auto-complete-helper.js @@ -26,7 +26,7 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -module.exports = function($http) { +module.exports = function($http, PathHelper) { var getAtWhoParameters = function(url) { return { at: '#', @@ -57,7 +57,7 @@ module.exports = function($http) { return { enableTextareaAutoCompletion: function(textareas) { angular.forEach(textareas, function(textarea) { - var url = angular.element(textarea).data('wp_autocomplete_url'); + var url = PathHelper.workPackageJsonAutoCompletePath(); if (url !== undefined && url.length > 0) { angular.element(textarea).atwho(getAtWhoParameters(url)); diff --git a/frontend/app/helpers/index.js b/frontend/app/helpers/index.js index c596fce6ee..2ba18bead4 100644 --- a/frontend/app/helpers/index.js +++ b/frontend/app/helpers/index.js @@ -28,7 +28,7 @@ angular.module('openproject.helpers') .constant('CUSTOM_FIELD_PREFIX', 'cf_') - .service('AutoCompleteHelper', ['$http', require('./auto-complete-helper')]) + .service('AutoCompleteHelper', ['$http', 'PathHelper', require('./auto-complete-helper')]) .service('CustomFieldHelper', ['CUSTOM_FIELD_PREFIX', 'I18n', require( './custom-field-helper')]) .service('PathHelper', require('./path-helper')) diff --git a/frontend/app/helpers/path-helper.js b/frontend/app/helpers/path-helper.js index b68250264d..437b2d4271 100644 --- a/frontend/app/helpers/path-helper.js +++ b/frontend/app/helpers/path-helper.js @@ -126,9 +126,6 @@ module.exports = function() { workPackagesBulkDeletePath: function() { return PathHelper.workPackagesPath() + '/bulk'; }, - workPackageAutoCompletePath: function(projectId, workPackageId) { - return '/work_packages/auto_complete?escape=false&id=' + workPackageId + '&project_id=' + projectId; - }, workPackageJsonAutoCompletePath: function() { return '/work_packages/auto_complete.json'; }, @@ -284,10 +281,6 @@ module.exports = function() { staticWorkPackagesAutocompletePath: function(projectId) { return PathHelper.staticBase + '/work_packages/auto_complete.json?project_id=' + projectId; }, - staticWorkPackageAutoCompletePath: function(projectId, workPackageId) { - return PathHelper.staticBase - + PathHelper.workPackageAutoCompletePath(projectId, workPackageId); - }, staticProjectWikiPath: function(projectId) { return PathHelper.staticProjectPath(projectId) + '/wiki'; }, diff --git a/frontend/app/templates/components/activity_comment.html b/frontend/app/templates/components/activity_comment.html index 3fb080759c..a3277c61fe 100644 --- a/frontend/app/templates/components/activity_comment.html +++ b/frontend/app/templates/components/activity_comment.html @@ -9,8 +9,7 @@ ng-model="$parent.activity.comment" required placeholder="{{ $parent.title }}" - ng-disabled="$parent.processingComment" - data-wp_autocomplete_url="{{ autocompletePath }}"> + ng-disabled="$parent.processingComment">