mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-15 13:45:25 +08:00
271 lines
9.5 KiB
Ruby
271 lines
9.5 KiB
Ruby
class SearchController < ApplicationController
|
|
include IconsHelper
|
|
include ProjectFoldersHelper
|
|
before_action :load_vars, only: :index
|
|
|
|
def index
|
|
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
|
|
|
|
case params[:group]
|
|
when 'projects'
|
|
@model = Project
|
|
search_by_name
|
|
|
|
render json: @records.includes(:team, :project_folder),
|
|
each_serializer: GlobalSearch::ProjectSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: (@records.next_page if @records.respond_to?(:next_page)),
|
|
}
|
|
when 'project_folders'
|
|
@model = ProjectFolder
|
|
search_by_name
|
|
|
|
render json: @records.includes(:team, :parent_folder),
|
|
each_serializer: GlobalSearch::ProjectFolderSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'reports'
|
|
@model = Report
|
|
search_by_name
|
|
|
|
render json: @records.includes(:team, :project, :user),
|
|
each_serializer: GlobalSearch::ReportSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'module_protocols'
|
|
@model = Protocol
|
|
search_by_name({ in_repository: false })
|
|
|
|
render json: @records.includes({ my_module: :experiment }, :team),
|
|
each_serializer: GlobalSearch::MyModuleProtocolSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'experiments'
|
|
@model = Experiment
|
|
search_by_name
|
|
|
|
render json: @records.includes(project: :team),
|
|
each_serializer: GlobalSearch::ExperimentSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'tasks'
|
|
@model = MyModule
|
|
search_by_name
|
|
|
|
render json: @records.includes(experiment: { project: :team }),
|
|
each_serializer: GlobalSearch::MyModuleSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'results'
|
|
@model = Result
|
|
search_by_name
|
|
|
|
render json: @records.includes(my_module: { experiment: { project: :team } }),
|
|
each_serializer: GlobalSearch::ResultSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'protocols'
|
|
@model = Protocol
|
|
search_by_name({ in_repository: true })
|
|
|
|
render json: @records,
|
|
each_serializer: GlobalSearch::ProtocolSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'label_templates'
|
|
return render json: [], meta: { disabled: true }, status: :ok unless LabelTemplate.enabled?
|
|
|
|
@model = LabelTemplate
|
|
search_by_name
|
|
|
|
render json: @records,
|
|
each_serializer: GlobalSearch::LabelTemplateSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'repository_rows'
|
|
@model = RepositoryRow
|
|
search_by_name(RepositoryRow)
|
|
|
|
render json: @records,
|
|
each_serializer: GlobalSearch::RepositoryRowSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
when 'assets'
|
|
@model = Asset
|
|
search_by_name
|
|
includes = [{ step: { protocol: { my_module: :experiment } } }, { result: { my_module: :experiment } }, :team]
|
|
|
|
render json: @records.includes(includes),
|
|
each_serializer: GlobalSearch::AssetSerializer,
|
|
meta: {
|
|
total: @records.total_count,
|
|
next_page: @records.next_page
|
|
}
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def new
|
|
end
|
|
|
|
def quick
|
|
results = if params[:filter].present?
|
|
object_quick_search(params[:filter].singularize)
|
|
else
|
|
Constants::QUICK_SEARCH_SEARCHABLE_OBJECTS.filter_map do |object|
|
|
next if object == 'label_template' && !LabelTemplate.enabled?
|
|
|
|
object_quick_search(object)
|
|
end.flatten.sort_by(&:updated_at).reverse.take(Constants::QUICK_SEARCH_LIMIT)
|
|
end
|
|
|
|
render json: results, each_serializer: QuickSearchSerializer
|
|
end
|
|
|
|
private
|
|
|
|
def object_quick_search(class_name)
|
|
search_model = class_name.to_s.camelize.constantize
|
|
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)
|
|
end
|
|
|
|
def load_vars
|
|
query = (params.fetch(:q) { '' }).strip
|
|
@filters = params[:filters]
|
|
@include_archived = @filters.blank? || @filters[:include_archived] == 'true'
|
|
@teams = (@filters.present? && @filters[:teams]&.values) || current_user.teams
|
|
@display_query = query
|
|
|
|
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.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)
|
|
else
|
|
@search_query.strip!
|
|
end
|
|
end
|
|
|
|
protected
|
|
|
|
def search_by_name(options = {})
|
|
@records = @model.search(current_user,
|
|
@include_archived,
|
|
@search_query,
|
|
nil,
|
|
teams: @teams,
|
|
users: @users,
|
|
options: options)
|
|
|
|
filter_records if @filters.present?
|
|
sort_records
|
|
paginate_records
|
|
end
|
|
|
|
def filter_records
|
|
filter_datetime!(:created_at) if @filters[:created_at].present?
|
|
filter_datetime!(:updated_at) if @filters[:updated_at].present?
|
|
filter_users! if @filters[:users].present?
|
|
end
|
|
|
|
def sort_records
|
|
@records = case params[:sort]
|
|
when 'atoz'
|
|
sort_attribute = @model.name == 'Asset' ? 'active_storage_blobs.filename' : 'name'
|
|
@records.order(sort_attribute => :asc)
|
|
when 'ztoa'
|
|
sort_attribute = @model.name == 'Asset' ? 'active_storage_blobs.filename' : 'name'
|
|
@records.order(sort_attribute => :desc)
|
|
when 'created_asc'
|
|
@records.order(created_at: :asc)
|
|
else
|
|
@records.order(created_at: :desc)
|
|
end
|
|
end
|
|
|
|
def paginate_records
|
|
@records = if params[:preview] == 'true'
|
|
@records.page(params[:page]).per(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
|
else
|
|
@records.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
|
end
|
|
end
|
|
|
|
def filter_datetime!(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
|
|
end
|
|
|
|
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?
|
|
|
|
@records = @records.where("#{model_name}.#{attribute} >= ?", from_date) if from_date.present?
|
|
@records = @records.where("#{model_name}.#{attribute} <= ?", to_date) if to_date.present?
|
|
end
|
|
|
|
def filter_users!
|
|
@records = @records.joins("INNER JOIN activities ON #{@model.model_name.collection}.id = activities.subject_id
|
|
AND activities.subject_type= '#{@model.name}'")
|
|
|
|
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
|
|
end
|
|
end
|