Commit ede08dbd authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Implement search page with filtering of results and pagination

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parent 9e5bc432
......@@ -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
......
......@@ -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
......@@ -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
......@@ -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
.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'
%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'
%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])}");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment