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 | +}; | ... | ... |