Commit 5d2bd5ec3a6d1c9ceb985e0af684f162926b0555

Authored by Dmitriy Zaporozhets
1 parent b2c13bdd

Simple search implementation

app/assets/javascripts/application.js
... ... @@ -11,6 +11,7 @@
11 11 //= require jquery.tagify
12 12 //= require jquery.cookie
13 13 //= require jquery.endless-scroll
  14 +//= require jquery.highlight
14 15 //= require bootstrap-modal
15 16 //= require modernizr
16 17 //= require chosen
... ...
app/assets/stylesheets/common.scss
... ... @@ -947,3 +947,7 @@ p.time {
947 947 padding: 4px;
948 948 margin: 2px;
949 949 }
  950 +
  951 +.highlight_word {
  952 + background:#EEDC94;
  953 +}
... ...
app/controllers/search_controller.rb 0 → 100644
... ... @@ -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 &lt; 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
... ... @@ -54,6 +54,10 @@ class Project &lt; ActiveRecord::Base
54 54 UsersProject.access_roles
55 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 61 def to_param
58 62 code
59 63 end
... ...
app/views/dashboard/_projects_feed.html.haml
1   -- @active_projects.first(5).each do |project|
  1 +- projects.first(5).each do |project|
2 2 .wll
3 3 = link_to project do
4 4 %h4
... ...
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
... ...
app/views/search/_result.html.haml 0 → 100644
No preview for this file type
app/views/search/show.html.haml 0 → 100644
... ... @@ -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 + &ndash;
  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
1 1 Gitlab::Application.routes.draw do
2   -
  2 + get 'search' => "search#show"
3 3  
4 4 # Optionally, enable Resque here
5 5 require 'resque/server'
... ...
vendor/assets/javascripts/jquery.highlight.js 0 → 100644
... ... @@ -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 +};
... ...