mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-27 10:14:17 +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…
Reference in a new issue