2016-02-12 23:52:43 +08:00
|
|
|
class SearchController < ApplicationController
|
2019-07-24 23:39:51 +08:00
|
|
|
include IconsHelper
|
2021-02-05 19:39:26 +08:00
|
|
|
include ProjectFoldersHelper
|
2017-06-28 21:44:18 +08:00
|
|
|
before_action :load_vars, only: :index
|
2016-02-12 23:52:43 +08:00
|
|
|
|
|
|
|
def index
|
2024-03-21 22:56:35 +08:00
|
|
|
respond_to do |format|
|
|
|
|
format.html do
|
|
|
|
redirect_to new_search_path unless @search_query
|
|
|
|
end
|
|
|
|
format.json do
|
|
|
|
redirect_to new_search_path unless @search_query
|
|
|
|
|
2024-03-22 23:37:59 +08:00
|
|
|
case params[:group]
|
|
|
|
when 'projects'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Project)
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(:team, :project_folder),
|
2024-03-22 23:37:59 +08:00
|
|
|
each_serializer: GlobalSearch::ProjectSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: (@records.next_page if @records.respond_to?(:next_page)),
|
|
|
|
}
|
2024-03-27 18:44:52 +08:00
|
|
|
when 'project_folders'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(ProjectFolder)
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(:team, :parent_folder),
|
2024-03-27 18:44:52 +08:00
|
|
|
each_serializer: GlobalSearch::ProjectFolderSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-03-27 18:44:52 +08:00
|
|
|
}
|
2024-03-22 23:37:59 +08:00
|
|
|
return
|
2024-04-04 14:32:37 +08:00
|
|
|
when 'reports'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Report)
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(:team, :project, :user),
|
2024-04-04 14:32:37 +08:00
|
|
|
each_serializer: GlobalSearch::ReportSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-04-04 14:32:37 +08:00
|
|
|
}
|
|
|
|
return
|
2024-03-28 18:16:49 +08:00
|
|
|
when 'module_protocols'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Protocol, { in_repository: false })
|
|
|
|
|
2024-05-15 17:59:05 +08:00
|
|
|
render json: @records.includes({ my_module: :experiment }, :team),
|
2024-03-28 18:16:49 +08:00
|
|
|
each_serializer: GlobalSearch::MyModuleProtocolSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-03-28 18:16:49 +08:00
|
|
|
}
|
|
|
|
return
|
2024-03-29 15:34:13 +08:00
|
|
|
when 'experiments'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Experiment)
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(project: :team),
|
2024-03-29 15:34:13 +08:00
|
|
|
each_serializer: GlobalSearch::ExperimentSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-03-29 15:34:13 +08:00
|
|
|
}
|
|
|
|
return
|
2024-03-29 15:47:42 +08:00
|
|
|
when 'tasks'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(MyModule)
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(experiment: { project: :team }),
|
2024-03-29 15:47:42 +08:00
|
|
|
each_serializer: GlobalSearch::MyModuleSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-03-29 15:47:42 +08:00
|
|
|
}
|
|
|
|
return
|
2024-03-29 16:27:33 +08:00
|
|
|
when 'results'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Result)
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(my_module: { experiment: { project: :team } }),
|
2024-03-29 16:27:33 +08:00
|
|
|
each_serializer: GlobalSearch::ResultSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-03-29 16:27:33 +08:00
|
|
|
}
|
|
|
|
return
|
2024-03-26 23:42:36 +08:00
|
|
|
when 'protocols'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Protocol, { in_repository: true })
|
2024-03-26 23:42:36 +08:00
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records,
|
2024-03-26 23:42:36 +08:00
|
|
|
each_serializer: GlobalSearch::ProtocolSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-04-03 07:04:20 +08:00
|
|
|
}
|
2024-03-27 19:41:30 +08:00
|
|
|
return
|
|
|
|
when 'label_templates'
|
|
|
|
return render json: [], meta: { disabled: true }, status: :ok unless LabelTemplate.enabled?
|
|
|
|
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(LabelTemplate)
|
2024-03-27 19:41:30 +08:00
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records,
|
2024-03-27 19:41:30 +08:00
|
|
|
each_serializer: GlobalSearch::LabelTemplateSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-04-03 07:04:20 +08:00
|
|
|
}
|
2024-03-26 23:42:36 +08:00
|
|
|
return
|
2024-04-03 06:55:09 +08:00
|
|
|
when 'repository_rows'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(RepositoryRow)
|
2024-04-03 06:55:09 +08:00
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records,
|
2024-04-03 06:55:09 +08:00
|
|
|
each_serializer: GlobalSearch::RepositoryRowSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-04-03 07:23:37 +08:00
|
|
|
}
|
2024-04-03 06:55:09 +08:00
|
|
|
return
|
2024-04-04 17:51:01 +08:00
|
|
|
when 'assets'
|
2024-04-30 15:27:15 +08:00
|
|
|
search_by_name(Asset)
|
2024-04-04 17:51:01 +08:00
|
|
|
includes = [{ step: { protocol: { my_module: :experiment } } }, { result: { my_module: :experiment } }, :team]
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
render json: @records.includes(includes),
|
2024-04-04 17:51:01 +08:00
|
|
|
each_serializer: GlobalSearch::AssetSerializer,
|
|
|
|
meta: {
|
2024-04-30 15:27:15 +08:00
|
|
|
total: @records.total_count,
|
|
|
|
next_page: @records.next_page
|
2024-04-04 17:51:01 +08:00
|
|
|
}
|
|
|
|
return
|
2024-03-21 22:56:35 +08:00
|
|
|
end
|
|
|
|
end
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def new
|
|
|
|
end
|
|
|
|
|
2024-02-23 21:08:51 +08:00
|
|
|
def quick
|
2024-02-27 19:10:27 +08:00
|
|
|
results = if params[:filter].present?
|
2024-04-16 19:52:53 +08:00
|
|
|
object_quick_search(params[:filter].singularize)
|
2024-02-27 19:10:27 +08:00
|
|
|
else
|
|
|
|
Constants::QUICK_SEARCH_SEARCHABLE_OBJECTS.filter_map do |object|
|
|
|
|
next if object == 'label_template' && !LabelTemplate.enabled?
|
|
|
|
|
2024-04-16 19:52:53 +08:00
|
|
|
object_quick_search(object)
|
2024-02-27 19:10:27 +08:00
|
|
|
end.flatten.sort_by(&:updated_at).reverse.take(Constants::QUICK_SEARCH_LIMIT)
|
|
|
|
end
|
2024-02-23 21:08:51 +08:00
|
|
|
|
|
|
|
render json: results, each_serializer: QuickSearchSerializer
|
|
|
|
end
|
|
|
|
|
2016-02-12 23:52:43 +08:00
|
|
|
private
|
|
|
|
|
2024-04-16 19:52:53 +08:00
|
|
|
def object_quick_search(class_name)
|
|
|
|
search_model = class_name.to_s.camelize.constantize
|
2024-05-16 20:00:36 +08:00
|
|
|
search_object_classes = ["#{class_name.pluralize}.name"]
|
|
|
|
search_object_classes << search_model::PREFIXED_ID_SQL if search_model.respond_to?(:code)
|
|
|
|
|
|
|
|
search_model.search_by_search_fields_with_boolean(current_user,
|
|
|
|
current_team,
|
|
|
|
params[:query],
|
|
|
|
search_object_classes,
|
|
|
|
limit: Constants::QUICK_SEARCH_LIMIT,
|
|
|
|
fetch_latest_versions: class_name == 'protocol')
|
|
|
|
.order(updated_at: :desc)
|
2024-02-27 19:10:27 +08:00
|
|
|
end
|
|
|
|
|
2016-02-12 23:52:43 +08:00
|
|
|
def load_vars
|
2017-05-09 00:00:14 +08:00
|
|
|
query = (params.fetch(:q) { '' }).strip
|
2024-04-18 21:45:34 +08:00
|
|
|
@filters = params[:filters]
|
2024-04-26 17:14:42 +08:00
|
|
|
@include_archived = @filters.blank? || @filters[:include_archived] == 'true'
|
|
|
|
@teams = (@filters.present? && @filters[:teams]&.values) || current_user.teams
|
2017-05-05 22:41:23 +08:00
|
|
|
@display_query = query
|
|
|
|
|
2024-04-18 21:45:34 +08:00
|
|
|
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]} "
|
2017-05-05 22:41:23 +08:00
|
|
|
end
|
2024-04-18 21:45:34 +08:00
|
|
|
end
|
|
|
|
if @search_query.blank?
|
|
|
|
flash[:error] = t('general.query.wrong_query',
|
|
|
|
min_length: Constants::NAME_MIN_LENGTH,
|
|
|
|
max_length: Constants::TEXT_MAX_LENGTH)
|
|
|
|
redirect_back(fallback_location: root_path)
|
2017-05-05 22:41:23 +08:00
|
|
|
else
|
2024-04-18 21:45:34 +08:00
|
|
|
@search_query.strip!
|
2016-07-21 19:11:15 +08:00
|
|
|
end
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
2016-07-26 16:55:27 +08:00
|
|
|
|
2016-02-12 23:52:43 +08:00
|
|
|
protected
|
|
|
|
|
2024-04-30 15:27:15 +08:00
|
|
|
def search_by_name(model, options = {})
|
2024-04-26 17:14:42 +08:00
|
|
|
@records = model.search(current_user,
|
|
|
|
@include_archived,
|
|
|
|
@search_query,
|
|
|
|
nil,
|
|
|
|
teams: @teams,
|
|
|
|
users: @users,
|
|
|
|
options: options)
|
|
|
|
|
|
|
|
filter_records(model) if @filters.present?
|
|
|
|
sort_records
|
2024-04-30 15:27:15 +08:00
|
|
|
paginate_records
|
2016-07-21 19:11:15 +08:00
|
|
|
end
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
def filter_records(model)
|
|
|
|
filter_datetime!(model, :created_at) if @filters[:created_at].present?
|
|
|
|
filter_datetime!(model, :updated_at) if @filters[:updated_at].present?
|
|
|
|
filter_users!(model) if @filters[:users].present?
|
|
|
|
end
|
2024-04-18 21:45:34 +08:00
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
def sort_records
|
|
|
|
@records = case params[:sort]
|
|
|
|
when 'atoz'
|
|
|
|
@records.order(name: :asc)
|
|
|
|
when 'ztoa'
|
|
|
|
@records.order(name: :desc)
|
|
|
|
when 'created_asc'
|
|
|
|
@records.order(created_at: :asc)
|
|
|
|
else
|
|
|
|
@records.order(created_at: :desc)
|
|
|
|
end
|
|
|
|
end
|
2024-04-18 21:45:34 +08:00
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
def paginate_records
|
|
|
|
@records = if params[:preview] == 'true'
|
2024-04-30 15:27:15 +08:00
|
|
|
@records.page(params[:page]).per(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
2024-04-26 17:14:42 +08:00
|
|
|
else
|
|
|
|
@records.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
|
|
|
end
|
|
|
|
end
|
2024-04-18 21:45:34 +08:00
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
def filter_datetime!(model, attribute)
|
|
|
|
model_name = model.model_name.collection
|
|
|
|
if @filters[attribute][:on].present?
|
|
|
|
from_date = Time.zone.parse(@filters[attribute][:on]).beginning_of_day.utc
|
|
|
|
to_date = Time.zone.parse(@filters[attribute][:on]).end_of_day.utc
|
2024-04-18 21:45:34 +08:00
|
|
|
end
|
|
|
|
|
2024-05-15 21:29:00 +08:00
|
|
|
from_date = Time.zone.parse(@filters[attribute][:from]) if @filters[attribute][:from].present?
|
|
|
|
to_date = Time.zone.parse(@filters[attribute][:to]) if @filters[attribute][:to].present?
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
@records = @records.where("#{model_name}.#{attribute} >= ?", from_date) if from_date.present?
|
|
|
|
@records = @records.where("#{model_name}.#{attribute} <= ?", to_date) if to_date.present?
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
|
2024-04-26 17:14:42 +08:00
|
|
|
def filter_users!(model)
|
|
|
|
@records = @records.joins("INNER JOIN activities ON #{model.model_name.collection}.id = activities.subject_id
|
|
|
|
AND activities.subject_type= '#{model.name}'")
|
2024-05-20 19:20:13 +08:00
|
|
|
|
|
|
|
user_ids = @filters[:users]&.values
|
|
|
|
@records = if model.name == 'MyModule'
|
|
|
|
@records.where('activities.owner_id IN (?) OR users.id IN (?)', user_ids, user_ids)
|
|
|
|
else
|
|
|
|
@records.where('activities.owner_id': user_ids)
|
|
|
|
end
|
2016-02-12 23:52:43 +08:00
|
|
|
end
|
|
|
|
end
|