From ede08dbdd787fdd3a30b62dc0e7e2c796bb6d43a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> Date: Wed, 27 Aug 2014 09:57:50 +0300 Subject: [PATCH] Implement search page with filtering of results and pagination Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> --- app/controllers/search_controller.rb | 23 ++++++--- app/helpers/search_helper.rb | 15 ++++++ app/services/search/global_service.rb | 20 +------- app/services/search/project_service.rb | 36 ++----------- app/views/search/_global_results.html.haml | 32 ++++++++++-- app/views/search/_project_results.html.haml | 56 +++++++++++++-------- app/views/search/_results.html.haml | 3 +- 7 files changed, 98 insertions(+), 87 deletions(-) diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 8df84e9884a..a58b24de643 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -4,14 +4,25 @@ class SearchController < ApplicationController def show @project = Project.find_by(id: params[:project_id]) if params[:project_id].present? @group = Group.find_by(id: params[:group_id]) if params[:group_id].present? + @scope = params[:scope] - if @project - return access_denied! unless can?(current_user, :download_code, @project) + @search_results = if @project + return access_denied! unless can?(current_user, :download_code, @project) - @search_results = Search::ProjectService.new(@project, current_user, params).execute - else - @search_results = Search::GlobalService.new(current_user, params).execute - end + unless %w(blobs notes issues merge_requests).include?(@scope) + @scope = 'blobs' + end + + Search::ProjectService.new(@project, current_user, params).execute + else + unless %w(projects issues merge_requests).include?(@scope) + @scope = 'projects' + end + + Search::GlobalService.new(current_user, params).execute + end + + @objects = @search_results.objects(@scope, params[:page]) end def autocomplete diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index ecd8d3994d0..8c805f79c36 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -91,4 +91,19 @@ module SearchHelper def search_result_sanitize(str) Sanitize.clean(str) end + + def search_filter_path(options={}) + exist_opts = { + search: params[:search], + project_id: params[:project_id], + group_id: params[:group_id], + scope: params[:scope] + } + + options = exist_opts.merge(options) + + path = request.path + path << "?#{options.to_param}" + path + end end diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index d213e1375e0..0bcc50c81a7 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -7,30 +7,12 @@ module Search end def execute - query = params[:search] - query = Shellwords.shellescape(query) if query.present? - return result unless query.present? - group = Group.find_by(id: params[:group_id]) if params[:group_id].present? projects = ProjectsFinder.new.execute(current_user) projects = projects.where(namespace_id: group.id) if group project_ids = projects.pluck(:id) - result[:projects] = projects.search(query).limit(20) - result[:merge_requests] = MergeRequest.in_projects(project_ids).search(query).order('updated_at DESC').limit(20) - result[:issues] = Issue.where(project_id: project_ids).search(query).order('updated_at DESC').limit(20) - result[:total_results] = %w(projects issues merge_requests).sum { |items| result[items.to_sym].size } - result - end - - def result - @result ||= { - projects: [], - merge_requests: [], - issues: [], - notes: [], - total_results: 0, - } + Gitlab::SearchResults.new(project_ids, params[:search]) end end end diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb index 8aac18840e4..f630c0a3790 100644 --- a/app/services/search/project_service.rb +++ b/app/services/search/project_service.rb @@ -7,39 +7,9 @@ module Search end def execute - query = params[:search] - query = Shellwords.shellescape(query) if query.present? - return result unless query.present? - - if params[:search_code].present? - if !@project.empty_repo? - blobs = project.repository.search_files(query, - params[:repository_ref]) - else - blobs = Array.new - end - - blobs = Kaminari.paginate_array(blobs).page(params[:page]).per(20) - result[:blobs] = blobs - result[:total_results] = blobs.total_count - else - result[:merge_requests] = project.merge_requests.search(query).order('updated_at DESC').limit(20) - result[:issues] = project.issues.where("title like :query OR description like :query ", query: "%#{query}%").order('updated_at DESC').limit(20) - result[:notes] = Note.where(noteable_type: 'issue').where(project_id: project.id).where("note like :query", query: "%#{query}%").order('updated_at DESC').limit(20) - result[:total_results] = %w(issues merge_requests notes).sum { |items| result[items.to_sym].size } - end - - result - end - - def result - @result ||= { - merge_requests: [], - issues: [], - blobs: [], - notes: [], - total_results: 0, - } + Gitlab::ProjectSearchResults.new(project.id, + params[:search], + params[:repository_ref]) end end end diff --git a/app/views/search/_global_results.html.haml b/app/views/search/_global_results.html.haml index 7f4f0e5e000..afecf1d3ac0 100644 --- a/app/views/search/_global_results.html.haml +++ b/app/views/search/_global_results.html.haml @@ -1,5 +1,27 @@ -.search_results - %ul.bordered-list - = render partial: "search/results/project", collection: @search_results[:projects] - = render partial: "search/results/merge_request", collection: @search_results[:merge_requests] - = render partial: "search/results/issue", collection: @search_results[:issues] +.row + .col-sm-3 + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if @scope == 'projects')} + = link_to search_filter_path(scope: 'projects') do + Projects + .pull-right + = @search_results.projects_count + %li{class: ("active" if @scope == 'issues')} + = link_to search_filter_path(scope: 'issues') do + Issues + .pull-right + = @search_results.issues_count + %li{class: ("active" if @scope == 'merge_requests')} + = link_to search_filter_path(scope: 'merge_requests') do + Merge requests + .pull-right + = @search_results.merge_requests_count + + .col-sm-9 + .search_results + - if @search_results.empty? + = render partial: "search/results/empty", locals: { message: "We couldn't find any matchind results" } + + %ul.bordered-list + = render partial: "search/results/#{@scope.singularize}", collection: @objects + = paginate @objects, theme: 'gitlab' diff --git a/app/views/search/_project_results.html.haml b/app/views/search/_project_results.html.haml index 5e8346a8262..35bc436dd18 100644 --- a/app/views/search/_project_results.html.haml +++ b/app/views/search/_project_results.html.haml @@ -1,24 +1,36 @@ -%ul.nav.nav-tabs - %li{class: ("active" if params[:search_code].present?)} - = link_to search_path(params.merge(search_code: true)) do - Repository Code - %li{class: ("active" if params[:search_code].blank?)} - = link_to search_path(params.merge(search_code: nil)) do - Issues and Merge requests +.row + .col-sm-3 + %ul.nav.nav-pills.nav-stacked + %li{class: ("active" if @scope == 'blobs')} + = link_to search_filter_path(scope: 'blobs') do + %i.icon-code + Code + .pull-right + = @search_results.blobs_count + %li{class: ("active" if @scope == 'issues')} + = link_to search_filter_path(scope: 'issues') do + %i.icon-exclamation-sign + Issues + .pull-right + = @search_results.issues_count + %li{class: ("active" if @scope == 'merge_requests')} + = link_to search_filter_path(scope: 'merge_requests') do + %i.icon-code-fork + Merge requests + .pull-right + = @search_results.merge_requests_count + %li{class: ("active" if @scope == 'notes')} + = link_to search_filter_path(scope: 'notes') do + %i.icon-comments + Comments + .pull-right + = @search_results.notes_count + + .col-sm-9 + .search_results + - if @search_results.empty? + = render partial: "search/results/empty", locals: { message: "We couldn't find any matchind results" } -.search_results - - if params[:search_code].present? - .blob-results - - if !@search_results[:blobs].empty? - = render partial: "search/results/blob", collection: @search_results[:blobs] - = paginate @search_results[:blobs], theme: 'gitlab' - - else - = render partial: "search/results/empty", :locals => { message: "We couldn't find any matching code" } - - else - - if @search_results[:merge_requests].present? || @search_results[:issues].present? || @search_results[:notes].present? %ul.bordered-list - = render partial: "search/results/merge_request", collection: @search_results[:merge_requests] - = render partial: "search/results/issue", collection: @search_results[:issues] - = render partial: "search/results/note", collection: @search_results[:notes] - - else - = render partial: "search/results/empty", locals: { message: "We couldn't find any issues, merge requests or notes" } + = render partial: "search/results/#{@scope.singularize}", collection: @objects + = paginate @objects, theme: 'gitlab' diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml index 2336d0f71d5..93bbe9cf7e9 100644 --- a/app/views/search/_results.html.haml +++ b/app/views/search/_results.html.haml @@ -1,5 +1,5 @@ %h4 - #{@search_results[:total_results]} results found + #{@search_results.total_count} results found - if @project for #{link_to @project.name_with_namespace, @project} - elsif @group @@ -14,4 +14,3 @@ :javascript $(".search_results .term").highlight("#{escape_javascript(params[:search])}"); - -- GitLab