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
@@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
11 | //= require jquery.tagify | 11 | //= require jquery.tagify |
12 | //= require jquery.cookie | 12 | //= require jquery.cookie |
13 | //= require jquery.endless-scroll | 13 | //= require jquery.endless-scroll |
14 | +//= require jquery.highlight | ||
14 | //= require bootstrap-modal | 15 | //= require bootstrap-modal |
15 | //= require modernizr | 16 | //= require modernizr |
16 | //= require chosen | 17 | //= require chosen |
app/assets/stylesheets/common.scss
@@ -0,0 +1,12 @@ | @@ -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,6 +37,10 @@ class MergeRequest < ActiveRecord::Base | ||
37 | scope :closed, where(:closed => true) | 37 | scope :closed, where(:closed => true) |
38 | scope :assigned, lambda { |u| where(:assignee_id => u.id)} | 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 | def validate_branches | 44 | def validate_branches |
41 | if target_branch == source_branch | 45 | if target_branch == source_branch |
42 | errors.add :base, "You can not use same branch for source and target branches" | 46 | errors.add :base, "You can not use same branch for source and target branches" |
app/models/project.rb
@@ -54,6 +54,10 @@ class Project < ActiveRecord::Base | @@ -54,6 +54,10 @@ class Project < ActiveRecord::Base | ||
54 | UsersProject.access_roles | 54 | UsersProject.access_roles |
55 | end | 55 | end |
56 | 56 | ||
57 | + def self.search query | ||
58 | + where("name like :query or code like :query or path like :query", :query => "%#{query}%") | ||
59 | + end | ||
60 | + | ||
57 | def to_param | 61 | def to_param |
58 | code | 62 | code |
59 | end | 63 | end |
app/views/dashboard/_projects_feed.html.haml
app/views/dashboard/index.html.haml
@@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
20 | .row | 20 | .row |
21 | .dashboard_block | 21 | .dashboard_block |
22 | .row | 22 | .row |
23 | - .span10= render "dashboard/projects_feed" | 23 | + .span10= render "dashboard/projects_feed", :projects => @active_projects |
24 | .span4.right | 24 | .span4.right |
25 | - if current_user.can_create_project? | 25 | - if current_user.can_create_project? |
26 | .alert-message.block-message.warning | 26 | .alert-message.block-message.warning |
app/views/layouts/_app_menu.html.haml
1 | %nav.main_menu | 1 | %nav.main_menu |
2 | = render "layouts/const_menu_links" | 2 | = render "layouts/const_menu_links" |
3 | = link_to "Projects", projects_path, :class => "#{"current" if current_page?(projects_path)}" | 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 | = link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" | 5 | = link_to "Issues", dashboard_issues_path, :class => "#{"current" if current_page?(dashboard_issues_path)}", :id => "issues_slide" |
5 | = link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" | 6 | = link_to "Requests", dashboard_merge_requests_path, :class => "#{"current" if current_page?(dashboard_merge_requests_path)}", :id => "merge_requests_slide" |
6 | = link_to "Help", help_path, :class => "#{"current" if controller.controller_name == "help"}" | 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 +7,9 @@ | ||
7 | %h1 | 7 | %h1 |
8 | GITLAB | 8 | GITLAB |
9 | %h1.project_name= title | 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 | - if current_user.is_admin? | 13 | - if current_user.is_admin? |
12 | = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do | 14 | = link_to admin_projects_path, :class => "admin_link", :title => "Admin area" do |
13 | = image_tag "admin.PNG", :width => 16 | 15 | = image_tag "admin.PNG", :width => 16 |
No preview for this file type
@@ -0,0 +1,41 @@ | @@ -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 @@ | @@ -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 | +}; |