mirror of
				https://github.com/scinote-eln/scinote-web.git
				synced 2025-11-04 12:07:23 +08:00 
			
		
		
		
	Add advanced search options [SCI-1158]
This commit is contained in:
		
							parent
							
								
									dbd9da916b
								
							
						
					
					
						commit
						0ee7e11620
					
				
					 21 changed files with 425 additions and 332 deletions
				
			
		
							
								
								
									
										12
									
								
								app/assets/javascripts/search.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/assets/javascripts/search.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
$(document.body).ready(function() {
 | 
			
		||||
  $('#search_whole_word').click(function() {
 | 
			
		||||
    if ($(this).prop('checked') === true) {
 | 
			
		||||
      $('#search_whole_phrase').prop('checked', false);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  $('#search_whole_phrase').click(function() {
 | 
			
		||||
    if ($(this).prop('checked') === true) {
 | 
			
		||||
      $('#search_whole_word').prop('checked', false);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -2,9 +2,7 @@ class SearchController < ApplicationController
 | 
			
		|||
  before_filter :load_vars, only: :index
 | 
			
		||||
 | 
			
		||||
  def index
 | 
			
		||||
    if not @search_query
 | 
			
		||||
      redirect_to new_search_path
 | 
			
		||||
    end
 | 
			
		||||
    redirect_to new_search_path unless @search_query
 | 
			
		||||
 | 
			
		||||
    count_search_results
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,47 +39,60 @@ class SearchController < ApplicationController
 | 
			
		|||
  private
 | 
			
		||||
 | 
			
		||||
  def load_vars
 | 
			
		||||
    @search_query = params[:q] || ''
 | 
			
		||||
    query = params[:q].strip || ''
 | 
			
		||||
    @search_category = params[:category] || ''
 | 
			
		||||
    @search_category = @search_category.to_sym
 | 
			
		||||
    @search_page = params[:page].to_i || 1
 | 
			
		||||
    @display_query = @search_query
 | 
			
		||||
    @search_case = params[:match_case] == 'true'
 | 
			
		||||
    @search_whole_word = params[:whole_word] == 'true'
 | 
			
		||||
    @search_whole_phrase = params[:whole_phrase] == 'true'
 | 
			
		||||
    @display_query = query
 | 
			
		||||
 | 
			
		||||
    if @search_query.length < Constants::NAME_MIN_LENGTH
 | 
			
		||||
      flash[:error] = t 'general.query.length_too_short',
 | 
			
		||||
                        min_length: Constants::NAME_MIN_LENGTH
 | 
			
		||||
      return redirect_to :back
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # splits the search query to validate all entries
 | 
			
		||||
    @splited_query = @search_query.split
 | 
			
		||||
 | 
			
		||||
    if @splited_query.first.length < Constants::NAME_MIN_LENGTH
 | 
			
		||||
      flash[:error] = t 'general.query.length_too_short',
 | 
			
		||||
                        min_length: Constants::NAME_MIN_LENGTH
 | 
			
		||||
      redirect_to :back
 | 
			
		||||
    elsif @splited_query.first.length > Constants::TEXT_MAX_LENGTH
 | 
			
		||||
      flash[:error] = t 'general.query.length_too_long',
 | 
			
		||||
                        max_length: Constants::TEXT_MAX_LENGTH
 | 
			
		||||
      redirect_to :back
 | 
			
		||||
    elsif @splited_query.length > 1
 | 
			
		||||
      @search_query = ''
 | 
			
		||||
      @splited_query.each_with_index do |w, i|
 | 
			
		||||
        if w.length >= Constants::NAME_MIN_LENGTH
 | 
			
		||||
          @search_query += "#{@splited_query[i]} "
 | 
			
		||||
        end
 | 
			
		||||
    if @search_whole_phrase || query.count(' ').zero?
 | 
			
		||||
      if query.length < Constants::NAME_MIN_LENGTH
 | 
			
		||||
        flash[:error] = t('general.query.length_too_short',
 | 
			
		||||
                          min_length: Constants::NAME_MIN_LENGTH)
 | 
			
		||||
        redirect_to :back
 | 
			
		||||
      elsif query.length > Constants::TEXT_MAX_LENGTH
 | 
			
		||||
        flash[:error] = t('general.query.length_too_long',
 | 
			
		||||
                          max_length: Constants::TEXT_MAX_LENGTH)
 | 
			
		||||
        redirect_to :back
 | 
			
		||||
      else
 | 
			
		||||
        @search_query = query
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      @search_query = @splited_query.join(' ')
 | 
			
		||||
      # splits the search query to validate all entries
 | 
			
		||||
      splited_query = query.split
 | 
			
		||||
      @search_query = ''
 | 
			
		||||
      splited_query.each_with_index do |w, i|
 | 
			
		||||
        if w.length >= Constants::NAME_MIN_LENGTH &&
 | 
			
		||||
           w.length <= Constants::TEXT_MAX_LENGTH
 | 
			
		||||
          @search_query += "#{splited_query[i]} "
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
      if @search_query.empty?
 | 
			
		||||
        flash[:error] = t('general.query.wrong_query',
 | 
			
		||||
                          min_length: Constants::NAME_MIN_LENGTH,
 | 
			
		||||
                          max_length: Constants::TEXT_MAX_LENGTH)
 | 
			
		||||
        redirect_to :back
 | 
			
		||||
      else
 | 
			
		||||
        @search_query.strip!
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    @search_page = 1 if @search_page < 1
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
 | 
			
		||||
  def search_by_name(model)
 | 
			
		||||
    model.search(current_user, true, @search_query, @search_page)
 | 
			
		||||
    model.search(current_user,
 | 
			
		||||
                 true,
 | 
			
		||||
                 @search_query,
 | 
			
		||||
                 @search_page,
 | 
			
		||||
                 nil,
 | 
			
		||||
                 match_case: @search_case,
 | 
			
		||||
                 whole_word: @search_whole_word,
 | 
			
		||||
                 whole_phrase: @search_whole_phrase)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def count_by_name(model)
 | 
			
		||||
| 
						 | 
				
			
			@ -122,16 +133,14 @@ class SearchController < ApplicationController
 | 
			
		|||
 | 
			
		||||
  def search_projects
 | 
			
		||||
    @project_results = []
 | 
			
		||||
    if @project_search_count > 0
 | 
			
		||||
      @project_results = search_by_name Project
 | 
			
		||||
    end
 | 
			
		||||
    @project_results = search_by_name(Project) if @project_search_count > 0
 | 
			
		||||
    @search_count = @project_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_experiments
 | 
			
		||||
    @experiment_results = []
 | 
			
		||||
    if @experiment_search_count > 0
 | 
			
		||||
      @experiment_results = search_by_name Experiment
 | 
			
		||||
      @experiment_results = search_by_name(Experiment)
 | 
			
		||||
    end
 | 
			
		||||
    @search_count = @experiment_search_count
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -139,96 +148,76 @@ class SearchController < ApplicationController
 | 
			
		|||
  def search_workflows
 | 
			
		||||
    @workflow_results = []
 | 
			
		||||
    if @workflow_search_count > 0
 | 
			
		||||
      @workflow_results = search_by_name MyModuleGroup
 | 
			
		||||
      @workflow_results = search_by_name(MyModuleGroup)
 | 
			
		||||
    end
 | 
			
		||||
    @search_count = @workflow_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_modules
 | 
			
		||||
    @module_results = []
 | 
			
		||||
    if @module_search_count > 0
 | 
			
		||||
      @module_results = search_by_name MyModule
 | 
			
		||||
    end
 | 
			
		||||
    @module_results = search_by_name(MyModule) if @module_search_count > 0
 | 
			
		||||
    @search_count = @module_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_results
 | 
			
		||||
    @result_results = []
 | 
			
		||||
    if @result_search_count > 0
 | 
			
		||||
      @result_results = search_by_name Result
 | 
			
		||||
    end
 | 
			
		||||
    @result_results = search_by_name(Result) if @result_search_count > 0
 | 
			
		||||
    @search_count = @result_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_tags
 | 
			
		||||
    @tag_results = []
 | 
			
		||||
    if @tag_search_count > 0
 | 
			
		||||
      @tag_results = search_by_name Tag
 | 
			
		||||
    end
 | 
			
		||||
    @tag_results = search_by_name(Tag) if @tag_search_count > 0
 | 
			
		||||
    @search_count = @tag_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_reports
 | 
			
		||||
    @report_results = []
 | 
			
		||||
    if @report_search_count > 0
 | 
			
		||||
      @report_results = search_by_name Report
 | 
			
		||||
    end
 | 
			
		||||
    @report_results = search_by_name(Report) if @report_search_count > 0
 | 
			
		||||
    @search_count = @report_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_protocols
 | 
			
		||||
    @protocol_results = []
 | 
			
		||||
    if @protocol_search_count > 0
 | 
			
		||||
      @protocol_results = search_by_name Protocol
 | 
			
		||||
    end
 | 
			
		||||
    @protocol_results = search_by_name(Protocol) if @protocol_search_count > 0
 | 
			
		||||
    @search_count = @protocol_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_steps
 | 
			
		||||
    @step_results = []
 | 
			
		||||
    if @step_search_count > 0
 | 
			
		||||
      @step_results = search_by_name Step
 | 
			
		||||
    end
 | 
			
		||||
    @step_results = search_by_name(Step) if @step_search_count > 0
 | 
			
		||||
    @search_count = @step_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_checklists
 | 
			
		||||
    @checklist_results = []
 | 
			
		||||
    if @checklist_search_count > 0
 | 
			
		||||
      @checklist_results = search_by_name Checklist
 | 
			
		||||
      @checklist_results = search_by_name(Checklist)
 | 
			
		||||
    end
 | 
			
		||||
    @search_count = @checklist_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_samples
 | 
			
		||||
    @sample_results = []
 | 
			
		||||
    if @sample_search_count > 0
 | 
			
		||||
      @sample_results = search_by_name Sample
 | 
			
		||||
    end
 | 
			
		||||
    @sample_results = search_by_name(Sample) if @sample_search_count > 0
 | 
			
		||||
    @search_count = @sample_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_assets
 | 
			
		||||
    @asset_results = []
 | 
			
		||||
    if @asset_search_count > 0
 | 
			
		||||
      @asset_results = search_by_name Asset
 | 
			
		||||
    end
 | 
			
		||||
    @asset_results = search_by_name(Asset) if @asset_search_count > 0
 | 
			
		||||
    @search_count = @asset_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_tables
 | 
			
		||||
    @table_results = []
 | 
			
		||||
    if @table_search_count > 0
 | 
			
		||||
      @table_results = search_by_name Table
 | 
			
		||||
    end
 | 
			
		||||
    @table_results = search_by_name(Table) if @table_search_count > 0
 | 
			
		||||
    @search_count = @table_search_count
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def search_comments
 | 
			
		||||
    @comment_results = []
 | 
			
		||||
    if @comment_search_count > 0
 | 
			
		||||
      @comment_results = search_by_name Comment
 | 
			
		||||
    end
 | 
			
		||||
    @comment_results = search_by_name(Comment) if @comment_search_count > 0
 | 
			
		||||
    @search_count = @comment_search_count
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,7 +91,9 @@ class Asset < ActiveRecord::Base
 | 
			
		|||
    user,
 | 
			
		||||
    include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1
 | 
			
		||||
    page = 1,
 | 
			
		||||
    _current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
    step_ids =
 | 
			
		||||
      Step
 | 
			
		||||
| 
						 | 
				
			
			@ -107,42 +109,67 @@ class Asset < ActiveRecord::Base
 | 
			
		|||
      .distinct
 | 
			
		||||
      .pluck('result_assets.id')
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Trim whitespace and replace it with OR character. Make prefixed
 | 
			
		||||
    # wildcard search term and escape special characters.
 | 
			
		||||
    # For example, search term 'demo project' is transformed to
 | 
			
		||||
    # 'demo:*|project:*' which makes word inclusive search with postfix
 | 
			
		||||
    # wildcard.
 | 
			
		||||
 | 
			
		||||
    s_query = query.gsub(/[!()&|:]/, " ")
 | 
			
		||||
      .strip
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t| t + ":*" }
 | 
			
		||||
      .join("|")
 | 
			
		||||
      .gsub('\'', '"')
 | 
			
		||||
 | 
			
		||||
    ids = Asset
 | 
			
		||||
    ids =
 | 
			
		||||
      Asset
 | 
			
		||||
      .select(:id)
 | 
			
		||||
      .distinct
 | 
			
		||||
      .joins("LEFT OUTER JOIN step_assets ON step_assets.asset_id = assets.id")
 | 
			
		||||
      .joins("LEFT OUTER JOIN result_assets ON result_assets.asset_id = assets.id")
 | 
			
		||||
      .joins("LEFT JOIN asset_text_data ON assets.id = asset_text_data.asset_id")
 | 
			
		||||
      .where("(step_assets.id IN (?) OR result_assets.id IN (?))", step_ids, result_ids)
 | 
			
		||||
      .where(
 | 
			
		||||
        "(assets.file_file_name ILIKE ANY (array[?]) " +
 | 
			
		||||
      .joins('LEFT OUTER JOIN step_assets ON step_assets.asset_id = assets.id')
 | 
			
		||||
      .joins('LEFT OUTER JOIN result_assets ON ' \
 | 
			
		||||
             'result_assets.asset_id = assets.id')
 | 
			
		||||
      .joins('LEFT JOIN asset_text_data ON ' \
 | 
			
		||||
             'assets.id = asset_text_data.asset_id')
 | 
			
		||||
      .where('(step_assets.id IN (?) OR result_assets.id IN (?))',
 | 
			
		||||
             step_ids, result_ids)
 | 
			
		||||
 | 
			
		||||
    a_query = s_query = ''
 | 
			
		||||
 | 
			
		||||
    if options[:whole_word].to_s == 'true' ||
 | 
			
		||||
       options[:whole_phrase].to_s == 'true'
 | 
			
		||||
      like = options[:match_case].to_s == 'true' ? '~' : '~*'
 | 
			
		||||
      s_query = query.gsub(/[!()&|:]/, ' ')
 | 
			
		||||
                     .strip
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| t + ':*' }
 | 
			
		||||
      if options[:whole_word].to_s == 'true'
 | 
			
		||||
        a_query = query.split
 | 
			
		||||
                       .map { |a| Regexp.escape(a) }
 | 
			
		||||
                       .join('|')
 | 
			
		||||
        s_query = s_query.join('|')
 | 
			
		||||
      else
 | 
			
		||||
        a_query = Regexp.escape(query)
 | 
			
		||||
        s_query = s_query.join('&')
 | 
			
		||||
      end
 | 
			
		||||
      a_query = '\\y(' + a_query + ')\\y'
 | 
			
		||||
      s_query = s_query.tr('\'', '"')
 | 
			
		||||
 | 
			
		||||
      ids = ids.where(
 | 
			
		||||
        "(trim_html_tags(assets.file_file_name) #{like} ? " \
 | 
			
		||||
        "OR asset_text_data.data_vector @@ to_tsquery(?))",
 | 
			
		||||
        a_query,
 | 
			
		||||
        s_query
 | 
			
		||||
      )
 | 
			
		||||
    else
 | 
			
		||||
      like = options[:match_case].to_s == 'true' ? 'LIKE' : 'ILIKE'
 | 
			
		||||
      a_query = query.split.map { |a| "%#{sanitize_sql_like(a)}%" }
 | 
			
		||||
 | 
			
		||||
      # Trim whitespace and replace it with OR character. Make prefixed
 | 
			
		||||
      # wildcard search term and escape special characters.
 | 
			
		||||
      # For example, search term 'demo project' is transformed to
 | 
			
		||||
      # 'demo:*|project:*' which makes word inclusive search with postfix
 | 
			
		||||
      # wildcard.
 | 
			
		||||
      s_query = query.gsub(/[!()&|:]/, ' ')
 | 
			
		||||
                     .strip
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| t + ':*' }
 | 
			
		||||
                     .join('|')
 | 
			
		||||
                     .tr('\'', '"')
 | 
			
		||||
      ids = ids.where(
 | 
			
		||||
        "(trim_html_tags(assets.file_file_name) #{like} ANY (array[?]) " \
 | 
			
		||||
        "OR asset_text_data.data_vector @@ to_tsquery(?))",
 | 
			
		||||
        a_query,
 | 
			
		||||
        s_query
 | 
			
		||||
      )
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page != Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			@ -152,11 +179,12 @@ class Asset < ActiveRecord::Base
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    Asset
 | 
			
		||||
      .joins("LEFT JOIN asset_text_data ON assets.id = asset_text_data.asset_id")
 | 
			
		||||
      .select("assets.*")
 | 
			
		||||
      .select("ts_headline(data, to_tsquery('" + s_query + "'),
 | 
			
		||||
        'StartSel=<mark>, StopSel=</mark>') headline")
 | 
			
		||||
      .where("assets.id IN (?)",  ids)
 | 
			
		||||
      .joins('LEFT JOIN asset_text_data ON ' \
 | 
			
		||||
             ' assets.id = asset_text_data.asset_id')
 | 
			
		||||
      .select('assets.*')
 | 
			
		||||
      .select("ts_headline(data, to_tsquery('" + s_query +
 | 
			
		||||
              "'), 'StartSel=<mark>, StopSel=</mark>') headline")
 | 
			
		||||
      .where('assets.id IN (?)', ids)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def is_image?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,27 +22,25 @@ class Checklist < ActiveRecord::Base
 | 
			
		|||
    reject_if: :all_blank,
 | 
			
		||||
    allow_destroy: true
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options= {})
 | 
			
		||||
    step_ids =
 | 
			
		||||
      Step
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = Checklist
 | 
			
		||||
        .distinct
 | 
			
		||||
        .where("checklists.step_id IN (?)", step_ids)
 | 
			
		||||
        .joins("LEFT JOIN checklist_items ON checklists.id = checklist_items.checklist_id")
 | 
			
		||||
        .where_attributes_like(["checklists.name",  "checklist_items.text"], a_query)
 | 
			
		||||
    new_query =
 | 
			
		||||
      Checklist
 | 
			
		||||
      .distinct
 | 
			
		||||
      .where('checklists.step_id IN (?)', step_ids)
 | 
			
		||||
      .joins('LEFT JOIN checklist_items ON ' \
 | 
			
		||||
             'checklists.id = checklist_items.checklist_id')
 | 
			
		||||
      .where_attributes_like(['checklists.name', 'checklist_items.text'],
 | 
			
		||||
                             query, options)
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,9 @@ class Comment < ActiveRecord::Base
 | 
			
		|||
    user,
 | 
			
		||||
    include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1
 | 
			
		||||
    page = 1,
 | 
			
		||||
    _current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
    project_ids =
 | 
			
		||||
      Project
 | 
			
		||||
| 
						 | 
				
			
			@ -34,16 +36,6 @@ class Comment < ActiveRecord::Base
 | 
			
		|||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
                     .gsub('_', '\\_')
 | 
			
		||||
                     .gsub('%', '\\%')
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| '%' + t + '%' }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query =
 | 
			
		||||
      Comment.distinct
 | 
			
		||||
             .joins(:user)
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +49,8 @@ class Comment < ActiveRecord::Base
 | 
			
		|||
               step_ids, 'StepComment',
 | 
			
		||||
               result_ids, 'ResultComment'
 | 
			
		||||
             )
 | 
			
		||||
             .where_attributes_like(['message', 'users.full_name'], a_query)
 | 
			
		||||
             .where_attributes_like(['message', 'users.full_name'],
 | 
			
		||||
                                    query, options)
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,36 +2,67 @@ module SearchableModel
 | 
			
		|||
  extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
  included do
 | 
			
		||||
 | 
			
		||||
    # Helper function for relations that
 | 
			
		||||
    # adds OR ILIKE where clause for all specified attributes
 | 
			
		||||
    # for the given search query
 | 
			
		||||
    scope :where_attributes_like, ->(attributes, query) do
 | 
			
		||||
    scope :where_attributes_like, lambda { |attributes, query, options = {}|
 | 
			
		||||
      return unless query
 | 
			
		||||
      attrs = []
 | 
			
		||||
      if attributes.blank? or query.blank?
 | 
			
		||||
      if attributes.blank?
 | 
			
		||||
        # Do nothing in this case
 | 
			
		||||
      elsif attributes.is_a? Symbol
 | 
			
		||||
        attrs = [attributes.to_s]
 | 
			
		||||
      elsif attributes.is_a? String
 | 
			
		||||
        attrs = [attributes]
 | 
			
		||||
      elsif attributes.is_a? Array
 | 
			
		||||
        attrs = attributes.collect { |a| a.to_s }
 | 
			
		||||
        attrs = attributes.collect(&:to_s)
 | 
			
		||||
      else
 | 
			
		||||
        raise ArgumentError, ":attributes must be an array, symbol or string"
 | 
			
		||||
        raise ArgumentError, ':attributes must be an array, symbol or string'
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      if query.is_a? Array
 | 
			
		||||
 | 
			
		||||
      if options[:whole_word].to_s == 'true' ||
 | 
			
		||||
         options[:whole_phrase].to_s == 'true'
 | 
			
		||||
        unless attrs.empty?
 | 
			
		||||
          like = options[:match_case].to_s == 'true' ? '~' : '~*'
 | 
			
		||||
 | 
			
		||||
          if options[:whole_word].to_s == 'true'
 | 
			
		||||
            a_query = query.split
 | 
			
		||||
                           .map { |a| Regexp.escape(a) }
 | 
			
		||||
                           .join('|')
 | 
			
		||||
          else
 | 
			
		||||
            a_query = Regexp.escape(query)
 | 
			
		||||
          end
 | 
			
		||||
          a_query = '\\y(' + a_query + ')\\y'
 | 
			
		||||
          where_str =
 | 
			
		||||
            (attrs.map.with_index do |a, i|
 | 
			
		||||
              "(trim_html_tags(#{a})) ILIKE ANY (array[ :t#{i}]) OR "
 | 
			
		||||
              "(trim_html_tags(#{a})) #{like} :t#{i} OR "
 | 
			
		||||
            end
 | 
			
		||||
            ).join[0..-5]
 | 
			
		||||
          vals = (attrs.map.with_index do |_, i|
 | 
			
		||||
                    ["t#{i}".to_sym, query]
 | 
			
		||||
                  end
 | 
			
		||||
                 ).to_h
 | 
			
		||||
          vals = (
 | 
			
		||||
            attrs.map.with_index do |_, i|
 | 
			
		||||
              ["t#{i}".to_sym, a_query]
 | 
			
		||||
            end
 | 
			
		||||
          ).to_h
 | 
			
		||||
 | 
			
		||||
          return where(where_str, vals)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      like = options[:match_case].to_s == 'true' ? 'LIKE' : 'ILIKE'
 | 
			
		||||
 | 
			
		||||
      if query.count(' ') > 0
 | 
			
		||||
        unless attrs.empty?
 | 
			
		||||
          a_query = query.split.map { |a| "%#{sanitize_sql_like(a)}%" }
 | 
			
		||||
          where_str =
 | 
			
		||||
            (attrs.map.with_index do |a, i|
 | 
			
		||||
              "(trim_html_tags(#{a})) #{like} ANY (array[:t#{i}]) OR "
 | 
			
		||||
            end
 | 
			
		||||
            ).join[0..-5]
 | 
			
		||||
          vals = (
 | 
			
		||||
            attrs.map.with_index do |_, i|
 | 
			
		||||
              ["t#{i}".to_sym, a_query]
 | 
			
		||||
            end
 | 
			
		||||
          ).to_h
 | 
			
		||||
 | 
			
		||||
          return where(where_str, vals)
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -39,15 +70,18 @@ module SearchableModel
 | 
			
		|||
        unless attrs.empty?
 | 
			
		||||
          where_str =
 | 
			
		||||
            (attrs.map.with_index do |a, i|
 | 
			
		||||
              "(trim_html_tags(#{a})) ILIKE :t#{i} OR "
 | 
			
		||||
              "(trim_html_tags(#{a})) #{like} :t#{i} OR "
 | 
			
		||||
            end
 | 
			
		||||
            ).join[0..-5]
 | 
			
		||||
          vals = (attrs.map.with_index { |_, i| ["t#{i}".to_sym, query.to_s] })
 | 
			
		||||
                 .to_h
 | 
			
		||||
          vals = (
 | 
			
		||||
            attrs.map.with_index do |_, i|
 | 
			
		||||
              ["t#{i}".to_sym, "%#{sanitize_sql_like(query.to_s)}%"]
 | 
			
		||||
            end
 | 
			
		||||
          ).to_h
 | 
			
		||||
 | 
			
		||||
          return where(where_str, vals)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    }
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,19 +39,14 @@ class Experiment < ActiveRecord::Base
 | 
			
		|||
    include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1,
 | 
			
		||||
    current_team = nil
 | 
			
		||||
    current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
    project_ids =
 | 
			
		||||
      Project
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = '%' + query.strip.gsub('_', '\\_').gsub('%', '\\%') + '%'
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if current_team
 | 
			
		||||
      projects_ids =
 | 
			
		||||
        Project
 | 
			
		||||
| 
						 | 
				
			
			@ -65,19 +60,19 @@ class Experiment < ActiveRecord::Base
 | 
			
		|||
      new_query =
 | 
			
		||||
        Experiment
 | 
			
		||||
        .where('experiments.project_id IN (?)', projects_ids)
 | 
			
		||||
        .where_attributes_like([:name], a_query)
 | 
			
		||||
        .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
      return include_archived ? new_query : new_query.is_archived(false)
 | 
			
		||||
    elsif include_archived
 | 
			
		||||
      new_query =
 | 
			
		||||
        Experiment
 | 
			
		||||
        .where(project: project_ids)
 | 
			
		||||
        .where_attributes_like([:name, :description], a_query)
 | 
			
		||||
        .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
    else
 | 
			
		||||
      new_query =
 | 
			
		||||
        Experiment
 | 
			
		||||
        .is_archived(false)
 | 
			
		||||
        .where(project: project_ids)
 | 
			
		||||
        .where_attributes_like([:name, :description], a_query)
 | 
			
		||||
        .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,19 +47,14 @@ class MyModule < ActiveRecord::Base
 | 
			
		|||
    include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1,
 | 
			
		||||
    current_team = nil
 | 
			
		||||
    current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
    exp_ids =
 | 
			
		||||
      Experiment
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = '%' + query.strip.gsub('_', '\\_').gsub('%', '\\%') + '%'
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if current_team
 | 
			
		||||
      experiments_ids = Experiment
 | 
			
		||||
                        .search(user,
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +66,7 @@ class MyModule < ActiveRecord::Base
 | 
			
		|||
      new_query = MyModule
 | 
			
		||||
                  .distinct
 | 
			
		||||
                  .where('my_modules.experiment_id IN (?)', experiments_ids)
 | 
			
		||||
                  .where_attributes_like([:name, :description], a_query)
 | 
			
		||||
                  .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
 | 
			
		||||
      if include_archived
 | 
			
		||||
        return new_query
 | 
			
		||||
| 
						 | 
				
			
			@ -82,13 +77,13 @@ class MyModule < ActiveRecord::Base
 | 
			
		|||
      new_query = MyModule
 | 
			
		||||
                  .distinct
 | 
			
		||||
                  .where('my_modules.experiment_id IN (?)', exp_ids)
 | 
			
		||||
                  .where_attributes_like([:name, :description], a_query)
 | 
			
		||||
                  .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
    else
 | 
			
		||||
      new_query = MyModule
 | 
			
		||||
                  .distinct
 | 
			
		||||
                  .where('my_modules.experiment_id IN (?)', exp_ids)
 | 
			
		||||
                  .where('my_modules.archived = ?', false)
 | 
			
		||||
                  .where_attributes_like([:name, :description], a_query)
 | 
			
		||||
                  .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,27 +11,21 @@ class MyModuleGroup < ActiveRecord::Base
 | 
			
		|||
  belongs_to :created_by, foreign_key: 'created_by_id', class_name: 'User'
 | 
			
		||||
  has_many :my_modules, inverse_of: :my_module_group, dependent: :nullify
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options = {})
 | 
			
		||||
    exp_ids =
 | 
			
		||||
      Experiment
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = MyModuleGroup
 | 
			
		||||
      .distinct
 | 
			
		||||
      .where("my_module_groups.experiment_id IN (?)", exp_ids)
 | 
			
		||||
      .where_attributes_like("my_module_groups.name", a_query)
 | 
			
		||||
                .distinct
 | 
			
		||||
                .where('my_module_groups.experiment_id IN (?)', exp_ids)
 | 
			
		||||
                .where_attributes_like('my_module_groups.name', query, options)
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,15 +31,10 @@ class Project < ActiveRecord::Base
 | 
			
		|||
    include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1,
 | 
			
		||||
    current_team = nil
 | 
			
		||||
    current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = '%' + query.strip.gsub('_', '\\_').gsub('%', '\\%') + '%'
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if current_team
 | 
			
		||||
      new_query =
 | 
			
		||||
        Project
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +48,7 @@ class Project < ActiveRecord::Base
 | 
			
		|||
          user.id
 | 
			
		||||
        )
 | 
			
		||||
      end
 | 
			
		||||
      new_query = new_query.where_attributes_like(:name, a_query)
 | 
			
		||||
      new_query = new_query.where_attributes_like(:name, query, options)
 | 
			
		||||
 | 
			
		||||
      if include_archived
 | 
			
		||||
        return new_query
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +70,7 @@ class Project < ActiveRecord::Base
 | 
			
		|||
            'user_projects.user_id = ?',
 | 
			
		||||
            user.id
 | 
			
		||||
          )
 | 
			
		||||
          .where_attributes_like('projects.name', a_query)
 | 
			
		||||
          .where_attributes_like('projects.name', query, options)
 | 
			
		||||
 | 
			
		||||
      else
 | 
			
		||||
        new_query =
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +81,7 @@ class Project < ActiveRecord::Base
 | 
			
		|||
            'user_projects.user_id = ?',
 | 
			
		||||
            user.id
 | 
			
		||||
          )
 | 
			
		||||
          .where_attributes_like('projects.name', a_query)
 | 
			
		||||
          .where_attributes_like('projects.name', query, options)
 | 
			
		||||
          .where('projects.archived = ?', false)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,7 +106,12 @@ class Protocol < ActiveRecord::Base
 | 
			
		|||
  has_many :protocol_keywords, through: :protocol_protocol_keywords
 | 
			
		||||
  has_many :steps, inverse_of: :protocol, dependent: :destroy
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options = {})
 | 
			
		||||
    team_ids = Team.joins(:user_teams)
 | 
			
		||||
                   .where('user_teams.user_id = ?', user.id)
 | 
			
		||||
                   .distinct
 | 
			
		||||
| 
						 | 
				
			
			@ -157,16 +162,6 @@ class Protocol < ActiveRecord::Base
 | 
			
		|||
                  )
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
                     .gsub('_', '\\_')
 | 
			
		||||
                     .gsub('%', '\\%')
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| '%' + t + '%' }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = new_query
 | 
			
		||||
                .distinct
 | 
			
		||||
                .joins('LEFT JOIN protocol_protocol_keywords ON ' \
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +176,7 @@ class Protocol < ActiveRecord::Base
 | 
			
		|||
                    'protocols.authors',
 | 
			
		||||
                    'protocol_keywords.name'
 | 
			
		||||
                  ],
 | 
			
		||||
                  a_query
 | 
			
		||||
                  query, options
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,9 @@ class Report < ActiveRecord::Base
 | 
			
		|||
    user,
 | 
			
		||||
    include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1
 | 
			
		||||
    page = 1,
 | 
			
		||||
    _current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
    project_ids =
 | 
			
		||||
| 
						 | 
				
			
			@ -30,28 +32,14 @@ class Report < ActiveRecord::Base
 | 
			
		|||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = Report
 | 
			
		||||
    new_query =
 | 
			
		||||
      Report
 | 
			
		||||
      .distinct
 | 
			
		||||
      .joins("LEFT OUTER JOIN users ON users.id = reports.user_id OR users.id = reports.last_modified_by_id")
 | 
			
		||||
      .where("reports.project_id IN (?)", project_ids)
 | 
			
		||||
      .where("reports.user_id = (?)", user.id)
 | 
			
		||||
      .where_attributes_like(
 | 
			
		||||
        [
 | 
			
		||||
          :name,
 | 
			
		||||
          :description
 | 
			
		||||
        ],
 | 
			
		||||
        a_query
 | 
			
		||||
      )
 | 
			
		||||
      .joins('LEFT OUTER JOIN users ON users.id = reports.user_id ' \
 | 
			
		||||
             'OR users.id = reports.last_modified_by_id')
 | 
			
		||||
      .where('reports.project_id IN (?)', project_ids)
 | 
			
		||||
      .where('reports.user_id = (?)', user.id)
 | 
			
		||||
      .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,30 +29,27 @@ class Result < ActiveRecord::Base
 | 
			
		|||
  accepts_nested_attributes_for :asset
 | 
			
		||||
  accepts_nested_attributes_for :table
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options = {})
 | 
			
		||||
    module_ids =
 | 
			
		||||
      MyModule
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = Result
 | 
			
		||||
    new_query =
 | 
			
		||||
      Result
 | 
			
		||||
      .distinct
 | 
			
		||||
      .joins("LEFT JOIN result_texts ON results.id = result_texts.result_id")
 | 
			
		||||
      .where("results.my_module_id IN (?)", module_ids)
 | 
			
		||||
      .where_attributes_like(["results.name", "result_texts.text"], a_query)
 | 
			
		||||
      .joins('LEFT JOIN result_texts ON results.id = result_texts.result_id')
 | 
			
		||||
      .where('results.my_module_id IN (?)', module_ids)
 | 
			
		||||
      .where_attributes_like(['results.name', 'result_texts.text'],
 | 
			
		||||
                             query, options)
 | 
			
		||||
 | 
			
		||||
    unless include_archived
 | 
			
		||||
      new_query = new_query.where("results.archived = ?", false)
 | 
			
		||||
      new_query = new_query.where('results.archived = ?', false)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,56 +19,51 @@ class Sample < ActiveRecord::Base
 | 
			
		|||
 | 
			
		||||
  def self.search(
 | 
			
		||||
    user,
 | 
			
		||||
    include_archived,
 | 
			
		||||
    _include_archived,
 | 
			
		||||
    query = nil,
 | 
			
		||||
    page = 1,
 | 
			
		||||
    current_team = nil
 | 
			
		||||
    current_team = nil,
 | 
			
		||||
    options = {}
 | 
			
		||||
  )
 | 
			
		||||
    team_ids = Team.joins(:user_teams)
 | 
			
		||||
                   .where('user_teams.user_id = ?', user.id)
 | 
			
		||||
                   .distinct
 | 
			
		||||
                   .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = '%' + query.strip.gsub('_', '\\_').gsub('%', '\\%') + '%'
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if current_team
 | 
			
		||||
      new_query = Sample
 | 
			
		||||
                  .distinct
 | 
			
		||||
                  .where('samples.team_id = ?', current_team.id)
 | 
			
		||||
                  .where_attributes_like(['samples.name'], a_query)
 | 
			
		||||
                  .where_attributes_like(['samples.name'], query, options)
 | 
			
		||||
 | 
			
		||||
      return new_query
 | 
			
		||||
    else
 | 
			
		||||
      user_ids = User
 | 
			
		||||
                 .joins(:user_teams)
 | 
			
		||||
                 .where('user_teams.team_id IN (?)', team_ids)
 | 
			
		||||
                 .where_attributes_like(['users.full_name'], a_query)
 | 
			
		||||
                 .where_attributes_like(['users.full_name'], query, options)
 | 
			
		||||
                 .pluck(:id)
 | 
			
		||||
 | 
			
		||||
      sample_ids = Sample
 | 
			
		||||
                   .joins(:user)
 | 
			
		||||
                   .where('team_id IN (?)', team_ids)
 | 
			
		||||
                   .where_attributes_like(['name'], a_query)
 | 
			
		||||
                   .where_attributes_like(['name'], query, options)
 | 
			
		||||
                   .pluck(:id)
 | 
			
		||||
 | 
			
		||||
      sample_type_ids = SampleType
 | 
			
		||||
                        .where('team_id IN (?)', team_ids)
 | 
			
		||||
                        .where_attributes_like(['name'], a_query)
 | 
			
		||||
                        .where_attributes_like(['name'], query, options)
 | 
			
		||||
                        .pluck(:id)
 | 
			
		||||
 | 
			
		||||
      sample_group_ids = SampleGroup
 | 
			
		||||
                         .where('team_id IN (?)', team_ids)
 | 
			
		||||
                         .where_attributes_like(['name'], a_query)
 | 
			
		||||
                         .where_attributes_like(['name'], query, options)
 | 
			
		||||
                         .pluck(:id)
 | 
			
		||||
 | 
			
		||||
      sample_custom_fields = SampleCustomField
 | 
			
		||||
                             .joins(:sample)
 | 
			
		||||
                             .where('samples.team_id IN (?)', team_ids)
 | 
			
		||||
                             .where_attributes_like(['value'], a_query)
 | 
			
		||||
                             .where_attributes_like(['value'], query, options)
 | 
			
		||||
                             .pluck(:id)
 | 
			
		||||
      new_query = Sample
 | 
			
		||||
                  .distinct
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,26 +41,21 @@ class Step < ActiveRecord::Base
 | 
			
		|||
  after_destroy :cascade_after_destroy
 | 
			
		||||
  before_save :set_last_modified_by
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options = {})
 | 
			
		||||
    protocol_ids =
 | 
			
		||||
      Protocol
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = Step
 | 
			
		||||
      .distinct
 | 
			
		||||
      .where("steps.protocol_id IN (?)", protocol_ids)
 | 
			
		||||
      .where_attributes_like([:name, :description], a_query)
 | 
			
		||||
                .distinct
 | 
			
		||||
                .where('steps.protocol_id IN (?)', protocol_ids)
 | 
			
		||||
                .where_attributes_like([:name, :description], query, options)
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,12 @@ class Table < ActiveRecord::Base
 | 
			
		|||
  after_save :update_ts_index
 | 
			
		||||
  #accepts_nested_attributes_for :table
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options = {})
 | 
			
		||||
    step_ids =
 | 
			
		||||
      Step
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
| 
						 | 
				
			
			@ -36,43 +41,63 @@ class Table < ActiveRecord::Base
 | 
			
		|||
      .distinct
 | 
			
		||||
      .pluck('result_tables.id')
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
                     .gsub('_', '\\_')
 | 
			
		||||
                     .gsub('%', '\\%')
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| '%' + t + '%' }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Trim whitespace and replace it with OR character. Make prefixed
 | 
			
		||||
    # wildcard search term and escape special characters.
 | 
			
		||||
    # For example, search term 'demo project' is transformed to
 | 
			
		||||
    # 'demo:*|project:*' which makes word inclusive search with postfix
 | 
			
		||||
    # wildcard.
 | 
			
		||||
    s_query = query.gsub(/[!()&|:]/, " ")
 | 
			
		||||
      .strip
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t| t + ":*" }
 | 
			
		||||
      .join("|")
 | 
			
		||||
      .gsub('\'', '"')
 | 
			
		||||
 | 
			
		||||
    table_query =
 | 
			
		||||
      Table
 | 
			
		||||
      .distinct
 | 
			
		||||
      .joins("LEFT OUTER JOIN step_tables ON step_tables.table_id = tables.id")
 | 
			
		||||
      .joins("LEFT OUTER JOIN result_tables ON result_tables.table_id = tables.id")
 | 
			
		||||
      .joins("LEFT OUTER JOIN results ON result_tables.result_id = results.id")
 | 
			
		||||
      .where("step_tables.id IN (?) OR result_tables.id IN (?)", step_ids, result_ids)
 | 
			
		||||
      .where(
 | 
			
		||||
        '(trim_html_tags(tables.name) ILIKE ANY (array[?])'\
 | 
			
		||||
        'OR tables.data_vector @@ to_tsquery(?))',
 | 
			
		||||
      .joins('LEFT OUTER JOIN step_tables ON step_tables.table_id = tables.id')
 | 
			
		||||
      .joins('LEFT OUTER JOIN result_tables ON ' \
 | 
			
		||||
             'result_tables.table_id = tables.id')
 | 
			
		||||
      .joins('LEFT OUTER JOIN results ON result_tables.result_id = results.id')
 | 
			
		||||
      .where('step_tables.id IN (?) OR result_tables.id IN (?)',
 | 
			
		||||
             step_ids, result_ids)
 | 
			
		||||
 | 
			
		||||
    if options[:whole_word].to_s == 'true' ||
 | 
			
		||||
       options[:whole_phrase].to_s == 'true'
 | 
			
		||||
      like = options[:match_case].to_s == 'true' ? '~' : '~*'
 | 
			
		||||
      s_query = query.gsub(/[!()&|:]/, ' ')
 | 
			
		||||
                     .strip
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| t + ':*' }
 | 
			
		||||
      if options[:whole_word].to_s == 'true'
 | 
			
		||||
        a_query = query.split
 | 
			
		||||
                       .map { |a| Regexp.escape(a) }
 | 
			
		||||
                       .join('|')
 | 
			
		||||
        s_query = s_query.join('|')
 | 
			
		||||
      else
 | 
			
		||||
        a_query = Regexp.escape(query)
 | 
			
		||||
        s_query = s_query.join('&')
 | 
			
		||||
      end
 | 
			
		||||
      a_query = '\\y(' + a_query + ')\\y'
 | 
			
		||||
      s_query = s_query.tr('\'', '"')
 | 
			
		||||
 | 
			
		||||
      new_query = table_query.where(
 | 
			
		||||
        "(trim_html_tags(tables.name) #{like} ?" \
 | 
			
		||||
        "OR tables.data_vector @@ to_tsquery(?))",
 | 
			
		||||
        a_query,
 | 
			
		||||
        s_query
 | 
			
		||||
      )
 | 
			
		||||
    else
 | 
			
		||||
      like = options[:match_case].to_s == 'true' ? 'LIKE' : 'ILIKE'
 | 
			
		||||
      a_query = query.split.map { |a| "%#{sanitize_sql_like(a)}%" }
 | 
			
		||||
 | 
			
		||||
    new_query = table_query
 | 
			
		||||
      # Trim whitespace and replace it with OR character. Make prefixed
 | 
			
		||||
      # wildcard search term and escape special characters.
 | 
			
		||||
      # For example, search term 'demo project' is transformed to
 | 
			
		||||
      # 'demo:*|project:*' which makes word inclusive search with postfix
 | 
			
		||||
      # wildcard.
 | 
			
		||||
      s_query = query.gsub(/[!()&|:]/, ' ')
 | 
			
		||||
                     .strip
 | 
			
		||||
                     .split(/\s+/)
 | 
			
		||||
                     .map { |t| t + ':*' }
 | 
			
		||||
                     .join('|')
 | 
			
		||||
                     .tr('\'', '"')
 | 
			
		||||
      new_query = table_query.where(
 | 
			
		||||
        "(trim_html_tags(tables.name) #{like} ANY (array[?])" \
 | 
			
		||||
        "OR tables.data_vector @@ to_tsquery(?))",
 | 
			
		||||
        a_query,
 | 
			
		||||
        s_query
 | 
			
		||||
      )
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,26 +16,21 @@ class Tag < ActiveRecord::Base
 | 
			
		|||
  has_many :my_module_tags, inverse_of: :tag, :dependent => :destroy
 | 
			
		||||
  has_many :my_modules, through: :my_module_tags
 | 
			
		||||
 | 
			
		||||
  def self.search(user, include_archived, query = nil, page = 1)
 | 
			
		||||
  def self.search(user,
 | 
			
		||||
                  include_archived,
 | 
			
		||||
                  query = nil,
 | 
			
		||||
                  page = 1,
 | 
			
		||||
                  _current_team = nil,
 | 
			
		||||
                  options = {})
 | 
			
		||||
    project_ids =
 | 
			
		||||
      Project
 | 
			
		||||
      .search(user, include_archived, nil, Constants::SEARCH_NO_LIMIT)
 | 
			
		||||
      .pluck(:id)
 | 
			
		||||
 | 
			
		||||
    if query
 | 
			
		||||
      a_query = query.strip
 | 
			
		||||
      .gsub("_","\\_")
 | 
			
		||||
      .gsub("%","\\%")
 | 
			
		||||
      .split(/\s+/)
 | 
			
		||||
      .map {|t|  "%" + t + "%" }
 | 
			
		||||
    else
 | 
			
		||||
      a_query = query
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    new_query = Tag
 | 
			
		||||
      .distinct
 | 
			
		||||
      .where("tags.project_id IN (?)", project_ids)
 | 
			
		||||
      .where_attributes_like(:name, a_query)
 | 
			
		||||
                .distinct
 | 
			
		||||
                .where('tags.project_id IN (?)', project_ids)
 | 
			
		||||
                .where_attributes_like(:name, query, options)
 | 
			
		||||
 | 
			
		||||
    # Show all results if needed
 | 
			
		||||
    if page == Constants::SEARCH_NO_LIMIT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +1,57 @@
 | 
			
		|||
<% provide(:head_title, t("search.index.head_title")) %>
 | 
			
		||||
 | 
			
		||||
<h1 class="page-header"><%= t('search.index.results_title_html', query: @display_query) %></h1>
 | 
			
		||||
<div class="page-header">
 | 
			
		||||
  <h1><%= t('search.index.results_title_html', query: @display_query) %></h1>
 | 
			
		||||
  <br>
 | 
			
		||||
  <!-- search form -->
 | 
			
		||||
  <div class="row">
 | 
			
		||||
    <div class="col-xs-12 col-sm-8 col-md-6">
 | 
			
		||||
      <%= form_tag search_path,
 | 
			
		||||
                   method: :get,
 | 
			
		||||
                   role: 'search' do %>
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
          <div class="input-group">
 | 
			
		||||
            <input class="form-control"
 | 
			
		||||
                   type="text"
 | 
			
		||||
                   name="q"
 | 
			
		||||
                   placeholder="<%= t('nav.search') %>"
 | 
			
		||||
                   value="<%= @display_query %>">
 | 
			
		||||
             <span class="input-group-btn">
 | 
			
		||||
              <button class="btn btn-default" type="submit">
 | 
			
		||||
                <span class="glyphicon glyphicon-search"></span>
 | 
			
		||||
              </button>
 | 
			
		||||
            </span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <label class="checkbox-inline">
 | 
			
		||||
            <input id="search_whole_word" type="checkbox" name="whole_word" value="true" <%= 'checked' if @search_whole_word %>><%= I18n.t('search.whole_word') %>
 | 
			
		||||
          </label>
 | 
			
		||||
          <label class="checkbox-inline">
 | 
			
		||||
            <input id="search_whole_phrase" type="checkbox" name="whole_phrase" value="true" <%= 'checked' if @search_whole_phrase %>><%= I18n.t('search.whole_phrase') %>
 | 
			
		||||
          </label>
 | 
			
		||||
          <label class="checkbox-inline">
 | 
			
		||||
            <input id="search_match_case" type="checkbox" name="match_case" value="true" <%= 'checked' if @search_case %>><%= I18n.t('search.match_case') %>
 | 
			
		||||
          </label>
 | 
			
		||||
        </div>
 | 
			
		||||
      <% end %>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<%= form_tag search_path, method: :get do %>
 | 
			
		||||
  <%= hidden_field_tag :q, @search_query %>
 | 
			
		||||
  <%= hidden_field_tag :category, @search_category %>
 | 
			
		||||
 | 
			
		||||
  <div class="row">
 | 
			
		||||
    <div class="col-xs-12 col-sm-3" id="search-menu">
 | 
			
		||||
    <div class="col-xs-12 col-sm-3 col-md-3" id="search-menu">
 | 
			
		||||
      <ul class="nav nav-pills nav-stacked nav-stacked-arrow">
 | 
			
		||||
        <li role="presentation"
 | 
			
		||||
          class="
 | 
			
		||||
          <%= "active" if @search_category.present? and @search_category == :projects %>
 | 
			
		||||
          <%= "disabled" if @project_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'projects', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'projects', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @project_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-blackboard"></span>
 | 
			
		||||
            <%= t'Projects' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +62,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :experiments %>
 | 
			
		||||
          <%= "disabled" if @experiment_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'experiments', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'experiments', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @experiment_search_count %></span>
 | 
			
		||||
            <%= fa_icon 'flask' %>
 | 
			
		||||
            <%= t'Experiments' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +75,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :workflows %>
 | 
			
		||||
          <%= "disabled" if @workflow_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'workflows', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'workflows', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @workflow_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-random"></span>
 | 
			
		||||
            <%= t'Workflows' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +88,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :modules %>
 | 
			
		||||
          <%= "disabled" if @module_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'modules', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'modules', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @module_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-credit-card"></span>
 | 
			
		||||
            <%= t'Modules' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +101,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :results %>
 | 
			
		||||
          <%= "disabled" if @result_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'results', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'results', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @result_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-modal-window"></span>
 | 
			
		||||
            <%= t'Results' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +114,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :tags %>
 | 
			
		||||
          <%= "disabled" if @tag_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'tags', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'tags', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @tag_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-tags"></span>
 | 
			
		||||
            <%= t'Tags' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +127,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :reports %>
 | 
			
		||||
          <%= "disabled" if @report_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'reports', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'reports', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @report_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-align-left"></span>
 | 
			
		||||
            <%= t'Reports' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +140,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :protocols %>
 | 
			
		||||
          <%= "disabled" if @protocol_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'protocols', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'protocols', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @protocol_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-list-alt"></span>
 | 
			
		||||
            <%= t'Protocols' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +153,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :steps %>
 | 
			
		||||
          <%= "disabled" if @step_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'steps', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'steps', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @step_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-circle-arrow-right"></span>
 | 
			
		||||
            <%= t'Steps' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +166,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :checklists %>
 | 
			
		||||
          <%= "disabled" if @checklist_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'checklists', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'checklists', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @checklist_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-list"></span>
 | 
			
		||||
            <%= t'Checklists' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +179,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :samples %>
 | 
			
		||||
          <%= "disabled" if @sample_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'samples', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'samples', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @sample_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-tint"></span>
 | 
			
		||||
            <%= t'Samples' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +192,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :assets %>
 | 
			
		||||
          <%= "disabled" if @asset_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'assets', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'assets', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @asset_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-file"></span>
 | 
			
		||||
            <%= t'Assets' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +205,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :tables %>
 | 
			
		||||
          <%= "disabled" if @table_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'tables', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'tables', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @table_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-th"></span>
 | 
			
		||||
            <%= t'Tables' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +218,9 @@
 | 
			
		|||
          <%= "active" if @search_category.present? and @search_category == :comments %>
 | 
			
		||||
          <%= "disabled" if @comment_search_count == 0 %>"
 | 
			
		||||
        >
 | 
			
		||||
          <a href="?<%= {category: 'comments', q: @search_query, utf8: '✓'}.to_query %>">
 | 
			
		||||
          <a href="?<%= {category: 'comments', q: @search_query,
 | 
			
		||||
                         whole_word: @search_whole_word, whole_phrase: @search_whole_phrase,
 | 
			
		||||
                         match_case: @search_case, utf8: '✓'}.to_query %>">
 | 
			
		||||
            <span class="badge pull-right"><%= @comment_search_count %></span>
 | 
			
		||||
            <span class="glyphicon glyphicon-comment"></span>
 | 
			
		||||
            <%= t'Comments' %>
 | 
			
		||||
| 
						 | 
				
			
			@ -251,3 +314,5 @@
 | 
			
		|||
  </ul>
 | 
			
		||||
</nav>
 | 
			
		||||
<% end %>
 | 
			
		||||
 | 
			
		||||
<%= javascript_include_tag('search') %>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@
 | 
			
		|||
  <!-- Display asset contents if it exists -->
 | 
			
		||||
  <% if asset.headline.present? && !asset.headline.empty? && asset.headline.include?("<mark>") %>
 | 
			
		||||
    <blockquote class="blockquote-search">
 | 
			
		||||
      <p><%= sanitize_input(asset.headline) %></p>
 | 
			
		||||
      <p><%= highlight(sanitize_input(asset.headline), search_query.strip.split(/\s+/)) %></p>
 | 
			
		||||
    </blockquote>
 | 
			
		||||
  <% end %>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,6 +71,7 @@ Rails.application.config.assets.precompile += %w(notifications.js)
 | 
			
		|||
Rails.application.config.assets.precompile += %w(users/invite_users_modal.js)
 | 
			
		||||
Rails.application.config.assets.precompile += %w(samples/sample_types_groups.js)
 | 
			
		||||
Rails.application.config.assets.precompile += %w(highlightjs-github-theme.css)
 | 
			
		||||
Rails.application.config.assets.precompile += %w(search.js)
 | 
			
		||||
 | 
			
		||||
# Libraries needed for Handsontable formulas
 | 
			
		||||
Rails.application.config.assets.precompile += %w(lodash.js)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,9 @@ en:
 | 
			
		|||
      archive: "Archive"
 | 
			
		||||
 | 
			
		||||
  search:
 | 
			
		||||
    whole_word: "Match any whole word"
 | 
			
		||||
    whole_phrase: "Match whole phrase"
 | 
			
		||||
    match_case: "Match case"
 | 
			
		||||
    index:
 | 
			
		||||
      head_title: "Search"
 | 
			
		||||
      page_title: "Search"
 | 
			
		||||
| 
						 | 
				
			
			@ -1597,6 +1600,7 @@ en:
 | 
			
		|||
      length_too_long: "is too long (maximum is %{max_length} characters)"
 | 
			
		||||
      length_too_short: "is too short (minimum is %{min_length} characters)"
 | 
			
		||||
    query:
 | 
			
		||||
      wrong_query: "All words in search query are either too short (minimum is %{min_length} characters) or too long (maximum is %{max_length} characters)"
 | 
			
		||||
      length_too_long: "Search query is too long (maximum is %{max_length} characters)"
 | 
			
		||||
      length_too_short: "Search query is too short (minimum is %{min_length} characters)"
 | 
			
		||||
    busy: "The server is still processing your request. If you leave this page, the changes will be lost! Are you sure you want to continue?"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue