summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-09-09 10:31:21 +0300
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-09-09 10:31:21 +0300
commit9e4a40982e25b31c0654b295fdf16d9aab2013f5 (patch)
tree9762e29c430952db283b577e001ea6d8f490d371 /app
parent002ce69e8fb1b1767967017175c7cfe66ec9d0ae (diff)
parent4561a09c69b9769ebdbbf7cb9a3ed8f8cc03651b (diff)
downloadgitlab-ce-9e4a40982e25b31c0654b295fdf16d9aab2013f5.tar.gz
Merge pull request #7646 from bushong1/snippet-search3
Adding in snippet search functionality
Diffstat (limited to 'app')
-rw-r--r--app/controllers/search_controller.rb7
-rw-r--r--app/helpers/application_helper.rb2
-rw-r--r--app/models/snippet.rb14
-rw-r--r--app/services/search/snippet_service.rb14
-rw-r--r--app/views/layouts/_search.html.haml2
-rw-r--r--app/views/search/_results.html.haml11
-rw-r--r--app/views/search/_snippet_filter.html.haml13
-rw-r--r--app/views/search/results/_snippet_blob.html.haml65
-rw-r--r--app/views/search/results/_snippet_title.html.haml23
-rw-r--r--app/views/search/show.html.haml6
10 files changed, 151 insertions, 6 deletions
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index a58b24de643..58ec8e75d7a 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -5,6 +5,7 @@ class SearchController < ApplicationController
@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]
+ @show_snippets = params[:snippets].eql? 'true'
@search_results = if @project
return access_denied! unless can?(current_user, :download_code, @project)
@@ -14,6 +15,12 @@ class SearchController < ApplicationController
end
Search::ProjectService.new(@project, current_user, params).execute
+ elsif @show_snippets
+ unless %w(snippet_blobs snippet_titles).include?(@scope)
+ @scope = 'snippet_blobs'
+ end
+
+ Search::SnippetService.new(current_user, params).execute
else
unless %w(projects issues merge_requests).include?(@scope)
@scope = 'projects'
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e6d50bea4d1..c2c9301cc17 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -178,6 +178,8 @@ module ApplicationHelper
def search_placeholder
if @project && @project.persisted?
"Search in this project"
+ elsif @snippet || @snippets || @show_snippets
+ 'Search snippets'
elsif @group && @group.persisted?
"Search in this group"
else
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 2c38e7939bd..80c1af8f337 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -65,4 +65,18 @@ class Snippet < ActiveRecord::Base
def expired?
expires_at && expires_at < Time.current
end
+
+ class << self
+ def search(query)
+ where('(title LIKE :query OR file_name LIKE :query)', query: "%#{query}%")
+ end
+
+ def search_code(query)
+ where('(content LIKE :query)', query: "%#{query}%")
+ end
+
+ def accessible_to(user)
+ where('private = ? OR author_id = ?', false, user)
+ end
+ end
end
diff --git a/app/services/search/snippet_service.rb b/app/services/search/snippet_service.rb
new file mode 100644
index 00000000000..8ca0877321d
--- /dev/null
+++ b/app/services/search/snippet_service.rb
@@ -0,0 +1,14 @@
+module Search
+ class SnippetService
+ attr_accessor :current_user, :params
+
+ def initialize(user, params)
+ @current_user, @params = user, params.dup
+ end
+
+ def execute
+ snippet_ids = Snippet.accessible_to(current_user).pluck(:id)
+ Gitlab::SnippetSearchResults.new(snippet_ids, params[:search])
+ end
+ end
+end
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index f485aee1e1a..5ab82122ad7 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -5,6 +5,8 @@
- if @project && @project.persisted?
= hidden_field_tag :project_id, @project.id
= hidden_field_tag :search_code, true
+ - if @snippet || @snippets
+ = hidden_field_tag :snippets, true
= hidden_field_tag :repository_ref, @ref
= submit_tag 'Go' if ENV['RAILS_ENV'] == 'test'
.search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref }
diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml
index f9c0a6d61ff..58bcff9dbe3 100644
--- a/app/views/search/_results.html.haml
+++ b/app/views/search/_results.html.haml
@@ -1,9 +1,10 @@
%h4
#{@search_results.total_count} results found
- - if @project
- for #{link_to @project.name_with_namespace, @project}
- - elsif @group
- for #{link_to @group.name, @group}
+ - unless @show_snippets
+ - if @project
+ for #{link_to @project.name_with_namespace, @project}
+ - elsif @group
+ for #{link_to @group.name, @group}
%hr
@@ -11,6 +12,8 @@
.col-sm-3
- if @project
= render "project_filter"
+ - elsif @show_snippets
+ = render 'snippet_filter'
- else
= render "global_filter"
.col-sm-9
diff --git a/app/views/search/_snippet_filter.html.haml b/app/views/search/_snippet_filter.html.haml
new file mode 100644
index 00000000000..0d1984a0d78
--- /dev/null
+++ b/app/views/search/_snippet_filter.html.haml
@@ -0,0 +1,13 @@
+%ul.nav.nav-pills.nav-stacked.search-filter
+ %li{class: ("active" if @scope == 'snippet_blobs')}
+ = link_to search_filter_path(scope: 'snippet_blobs', snippets: true, group_id: nil, project_id: nil) do
+ %i.icon-code
+ Snippet Contents
+ .pull-right
+ = @search_results.snippet_blobs_count
+ %li{class: ("active" if @scope == 'snippet_titles')}
+ = link_to search_filter_path(scope: 'snippet_titles', snippets: true, group_id: nil, project_id: nil) do
+ %i.icon-book
+ Titles and Filenames
+ .pull-right
+ = @search_results.snippet_titles_count
diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml
new file mode 100644
index 00000000000..a3d909d44dc
--- /dev/null
+++ b/app/views/search/results/_snippet_blob.html.haml
@@ -0,0 +1,65 @@
+.search-result-row
+ %span
+ = snippet_blob[:snippet_object].title
+ by
+ = link_to user_snippets_path(snippet_blob[:snippet_object].author) do
+ = image_tag avatar_icon(snippet_blob[:snippet_object].author_email), class: "avatar avatar-inline s16", alt: ''
+ = snippet_blob[:snippet_object].author_name
+ %span.light #{time_ago_with_tooltip(snippet_blob[:snippet_object].created_at)}
+ %h4.snippet-title
+ - snippet_path = reliable_snippet_path(snippet_blob[:snippet_object])
+ = link_to snippet_path do
+ .file-holder
+ .file-title
+ %i.icon-file
+ %strong= snippet_blob[:snippet_object].file_name
+ %span.options
+ .btn-group.tree-btn-group.pull-right
+ - if snippet_blob[:snippet_object].author == current_user
+ = link_to "Edit", edit_snippet_path(snippet_blob[:snippet_object]), class: "btn btn-tiny", title: 'Edit Snippet'
+ = link_to "Delete", snippet_path(snippet_blob[:snippet_object]), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-tiny", title: 'Delete Snippet'
+ = link_to "Raw", raw_snippet_path(snippet_blob[:snippet_object]), class: "btn btn-tiny", target: "_blank"
+ - if gitlab_markdown?(snippet_blob[:snippet_object].file_name)
+ .file-content.wiki
+ - snippet_blob[:snippet_chunks].each do |snippet|
+ - unless snippet[:data].empty?
+ = preserve do
+ = markdown(snippet[:data])
+ - else
+ .file-content.code
+ .nothing-here-block Empty file
+ - elsif markup?(snippet_blob[:snippet_object].file_name)
+ .file-content.wiki
+ - snippet_blob[:snippet_chunks].each do |snippet|
+ - unless snippet[:data].empty?
+ = render_markup(snippet_blob[:snippet_object].file_name, snippet[:data])
+ - else
+ .file-content.code
+ .nothing-here-block Empty file
+ - else
+ .file-content.code
+ %div.highlighted-data{class: user_color_scheme_class}
+ .line-numbers
+ - snippet_blob[:snippet_chunks].each do |snippet|
+ - unless snippet[:data].empty?
+ - snippet[:data].lines.to_a.size.times do |index|
+ - offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1
+ - i = index + offset
+ = link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}" do
+ %i.icon-link
+ = i
+ - unless snippet == snippet_blob[:snippet_chunks].last
+ %a
+ = "."
+ .highlight.term
+ %pre
+ %code
+ - snippet_blob[:snippet_chunks].each do |snippet|
+ - unless snippet[:data].empty?
+ = snippet[:data]
+ - unless snippet == snippet_blob[:snippet_chunks].last
+ %a
+ = "..."
+ - else
+ .file-content.code
+ .nothing-here-block Empty file
diff --git a/app/views/search/results/_snippet_title.html.haml b/app/views/search/results/_snippet_title.html.haml
new file mode 100644
index 00000000000..84abb9293b2
--- /dev/null
+++ b/app/views/search/results/_snippet_title.html.haml
@@ -0,0 +1,23 @@
+.search-result-row
+ %h4.snippet-title.term
+ = link_to reliable_snippet_path(snippet_title) do
+ = truncate(snippet_title.title, length: 60)
+ - if snippet_title.private?
+ %span.label.label-gray
+ %i.icon-lock
+ private
+ %span.cgray.monospace.tiny.pull-right.term
+ = snippet_title.file_name
+
+ %small.pull-right.cgray
+ - if snippet_title.project_id?
+ = link_to snippet_title.project.name_with_namespace, project_path(snippet_title.project)
+
+ .snippet-info
+ = "##{snippet_title.id}"
+ %span
+ by
+ = link_to user_snippets_path(snippet_title.author) do
+ = image_tag avatar_icon(snippet_title.author_email), class: "avatar avatar-inline s16", alt: ''
+ = snippet_title.author_name
+ %span.light #{time_ago_with_tooltip(snippet_title.created_at)}
diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml
index 8d1614bfbd4..bae57917a4c 100644
--- a/app/views/search/show.html.haml
+++ b/app/views/search/show.html.haml
@@ -9,10 +9,12 @@
= submit_tag 'Search', class: "btn btn-create"
.form-group
.col-sm-2
- .col-sm-10
- = render 'filter', f: f
+ - unless params[:snippets].eql? 'true'
+ .col-sm-10
+ = render 'filter', f: f
= hidden_field_tag :project_id, params[:project_id]
= hidden_field_tag :group_id, params[:group_id]
+ = hidden_field_tag :snippets, params[:snippets]
= hidden_field_tag :scope, params[:scope]
.results.prepend-top-10