Commit 5d2bd5ec3a6d1c9ceb985e0af684f162926b0555
1 parent
b2c13bdd
Exists in
master
and in
4 other branches
Simple search implementation
Showing
13 changed files
with
127 additions
and
4 deletions
Show diff stats
app/assets/javascripts/application.js
app/assets/stylesheets/common.scss
... | ... | @@ -0,0 +1,12 @@ |
1 | +class SearchController < ApplicationController | |
2 | + def show | |
3 | + query = params[:search] | |
4 | + if query.blank? | |
5 | + @projects = [] | |
6 | + @merge_requests = [] | |
7 | + else | |
8 | + @projects = Project.search(query).limit(10) | |
9 | + @merge_requests = MergeRequest.search(query).limit(10) | |
10 | + end | |
11 | + end | |
12 | +end | ... | ... |
app/models/merge_request.rb
... | ... | @@ -37,6 +37,10 @@ class MergeRequest < ActiveRecord::Base |
37 | 37 | scope :closed, where(:closed => true) |
38 | 38 | scope :assigned, lambda { |u| where(:assignee_id => u.id)} |
39 | 39 | |
40 | + def self.search query | |
41 | + where("title like :query", :query => "%#{query}%") | |
42 | + end | |
43 | + | |
40 | 44 | def validate_branches |
41 | 45 | if target_branch == source_branch |
42 | 46 | errors.add :base, "You can not use same branch for source and target branches" | ... | ... |
app/models/project.rb
app/views/dashboard/_projects_feed.html.haml
app/views/dashboard/index.html.haml
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | .row |
21 | 21 | .dashboard_block |
22 | 22 | .row |
23 | - .span10= render "dashboard/projects_feed" | |
23 | + .span10= render "dashboard/projects_feed", :projects => @active_projects | |
24 | 24 | .span4.right |
25 | 25 | - if current_user.can_create_project? |
26 | 26 | .alert-message.block-message.warning | ... | ... |
app/views/layouts/_app_menu.html.haml
1 | 1 | %nav.main_menu |
2 | 2 | = render "layouts/const_menu_links" |
3 | 3 | = link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}" |
4 | + = link_to "Search", search_path, :class => "#{"current" if current_page?(search_path)}" | |
4 | 5 | = link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" |
5 | 6 | = link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" |
6 | 7 | = link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}" | ... | ... |
app/views/layouts/_head_panel.html.haml
... | ... | @@ -7,7 +7,9 @@ |
7 | 7 | %h1 |
8 | 8 | GITLAB |
9 | 9 | %h1.project_name= title |
10 | - .search= text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" | |
10 | + .search | |
11 | + = form_tag search_path, :method => :get do |f| | |
12 | + = text_field_tag "search", nil, :placeholder => "Search", :class => "search-input" | |
11 | 13 | - if current_user.is_admin? |
12 | 14 | = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do |
13 | 15 | = image_tag "admin.PNG", :width => 16 | ... | ... |
No preview for this file type
... | ... | @@ -0,0 +1,41 @@ |
1 | += form_tag search_path, :method => :get do |f| | |
2 | + .padded | |
3 | + = label_tag :search, "Looking for" | |
4 | + .input | |
5 | + = text_field_tag :search, params[:search],:placeholder => "issue 143", :class => "xxlarge" | |
6 | + = submit_tag 'Search', :class => "btn primary" | |
7 | +- if params[:search].present? | |
8 | + %br | |
9 | + %h3 Search results | |
10 | + %hr | |
11 | + .search_results | |
12 | + - if @projects.empty? && @merge_requests.empty? | |
13 | + %h3 | |
14 | + %small Nothing here | |
15 | + - else | |
16 | + - if @projects.any? | |
17 | + - @projects.each do |project| | |
18 | + = link_to project do | |
19 | + %h4 | |
20 | + %span.ico.project | |
21 | + = project.name | |
22 | + %small | |
23 | + last activity at | |
24 | + = project.last_activity_date.stamp("Aug 25, 2011") | |
25 | + - if @merge_requests.any? | |
26 | + - @merge_requests.each do |merge_request| | |
27 | + = link_to [merge_request.project, merge_request] do | |
28 | + %h5 | |
29 | + Merge Request # | |
30 | + = merge_request.id | |
31 | + – | |
32 | + = truncate merge_request.title, :length => 50 | |
33 | + %small | |
34 | + updated at | |
35 | + = merge_request.updated_at.stamp("Aug 25, 2011") | |
36 | + %strong | |
37 | + %span.label= merge_request.project.name | |
38 | + :javascript | |
39 | + $(function() { | |
40 | + $(".search_results").highlight("#{params[:search]}"); | |
41 | + }) | ... | ... |
config/routes.rb
... | ... | @@ -0,0 +1,53 @@ |
1 | +/* | |
2 | + | |
3 | +highlight v3 | |
4 | + | |
5 | +Highlights arbitrary terms. | |
6 | + | |
7 | +<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html> | |
8 | + | |
9 | +MIT license. | |
10 | + | |
11 | +Johann Burkard | |
12 | +<http://johannburkard.de> | |
13 | +<mailto:jb@eaio.com> | |
14 | + | |
15 | +*/ | |
16 | + | |
17 | +jQuery.fn.highlight = function(pat) { | |
18 | + function innerHighlight(node, pat) { | |
19 | + var skip = 0; | |
20 | + if (node.nodeType == 3) { | |
21 | + var pos = node.data.toUpperCase().indexOf(pat); | |
22 | + if (pos >= 0) { | |
23 | + var spannode = document.createElement('span'); | |
24 | + spannode.className = 'highlight_word'; | |
25 | + var middlebit = node.splitText(pos); | |
26 | + var endbit = middlebit.splitText(pat.length); | |
27 | + var middleclone = middlebit.cloneNode(true); | |
28 | + spannode.appendChild(middleclone); | |
29 | + middlebit.parentNode.replaceChild(spannode, middlebit); | |
30 | + skip = 1; | |
31 | + } | |
32 | + } | |
33 | + else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { | |
34 | + for (var i = 0; i < node.childNodes.length; ++i) { | |
35 | + i += innerHighlight(node.childNodes[i], pat); | |
36 | + } | |
37 | + } | |
38 | + return skip; | |
39 | + } | |
40 | + return this.each(function() { | |
41 | + innerHighlight(this, pat.toUpperCase()); | |
42 | + }); | |
43 | +}; | |
44 | + | |
45 | +jQuery.fn.removeHighlight = function() { | |
46 | + return this.find("span.highlight").each(function() { | |
47 | + this.parentNode.firstChild.nodeName; | |
48 | + with (this.parentNode) { | |
49 | + replaceChild(this.firstChild, this); | |
50 | + normalize(); | |
51 | + } | |
52 | + }).end(); | |
53 | +}; | ... | ... |