mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-09 13:46:21 +08:00
Fix global search backend [SCI-10573]
This commit is contained in:
parent
3c4184c73e
commit
574c45b2c8
5 changed files with 117 additions and 172 deletions
|
|
@ -22,7 +22,7 @@ module Dashboard
|
|||
def project_filter
|
||||
projects = Project.readable_by_user(current_user)
|
||||
.search(current_user, false, params[:query], current_team)
|
||||
.page(1)
|
||||
.page(params[:page] || 1)
|
||||
.per(Constants::SEARCH_LIMIT)
|
||||
.select(:id, :name)
|
||||
projects = projects.map { |i| { value: i.id, label: escape_input(i.name) } }
|
||||
|
|
@ -39,7 +39,7 @@ module Dashboard
|
|||
experiments = @project.experiments
|
||||
.managable_by_user(current_user)
|
||||
.search(current_user, false, params[:query], current_team)
|
||||
.page(1)
|
||||
.page(params[:page] || 1)
|
||||
.per(Constants::SEARCH_LIMIT)
|
||||
.select(:id, :name)
|
||||
experiments = experiments.map { |i| { value: i.id, label: escape_input(i.name) } }
|
||||
|
|
|
|||
|
|
@ -15,120 +15,87 @@ class SearchController < ApplicationController
|
|||
when 'projects'
|
||||
@project_search_count = fetch_cached_count(Project)
|
||||
search_projects
|
||||
if params[:preview] == 'true'
|
||||
results = @project_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
results = @project_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
|
||||
render json: results.includes(:team, :project_folder),
|
||||
paginate_records
|
||||
render json: @records.includes(:team, :project_folder),
|
||||
each_serializer: GlobalSearch::ProjectSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: (results.next_page if results.respond_to?(:next_page)),
|
||||
next_page: (@records.next_page if @records.respond_to?(:next_page)),
|
||||
}
|
||||
when 'project_folders'
|
||||
@project_folder_search_count = fetch_cached_count ProjectFolder
|
||||
search_project_folders
|
||||
results = if params[:preview] == 'true'
|
||||
@project_folder_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@project_folder_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
render json: results.includes(:team, :parent_folder),
|
||||
paginate_records
|
||||
render json: @records.includes(:team, :parent_folder),
|
||||
each_serializer: GlobalSearch::ProjectFolderSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: results.try(:next_page)
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'reports'
|
||||
@report_search_count = fetch_cached_count Report
|
||||
search_reports
|
||||
results = if params[:preview] == 'true'
|
||||
@report_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@report_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
render json: results.includes(:team, :project, :user),
|
||||
paginate_records
|
||||
render json: @records.includes(:team, :project, :user),
|
||||
each_serializer: GlobalSearch::ReportSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: results.try(:next_page)
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'module_protocols'
|
||||
search_module_protocols
|
||||
results = if params[:preview] == 'true'
|
||||
@module_protocol_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@module_protocol_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
render json: results.joins({ my_module: :experiment }, :team),
|
||||
paginate_records
|
||||
render json: @records.joins({ my_module: :experiment }, :team),
|
||||
each_serializer: GlobalSearch::MyModuleProtocolSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: results.try(:next_page)
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'experiments'
|
||||
@experiment_search_count = fetch_cached_count Experiment
|
||||
search_experiments
|
||||
results = if params[:preview] == 'true'
|
||||
@experiment_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@experiment_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
render json: results.includes(project: :team),
|
||||
paginate_records
|
||||
render json: @records.includes(project: :team),
|
||||
each_serializer: GlobalSearch::ExperimentSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: results.try(:next_page)
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'tasks'
|
||||
@module_search_count = fetch_cached_count MyModule
|
||||
search_modules
|
||||
results = if params[:preview] == 'true'
|
||||
@module_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@module_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
render json: results.includes(experiment: { project: :team }),
|
||||
paginate_records
|
||||
render json: @records.includes(experiment: { project: :team }),
|
||||
each_serializer: GlobalSearch::MyModuleSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: results.try(:next_page)
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'results'
|
||||
@result_search_count = fetch_cached_count(Result)
|
||||
search_results
|
||||
results = if params[:preview] == 'true'
|
||||
@result_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@result_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
render json: results.includes(my_module: { experiment: { project: :team } }),
|
||||
paginate_records
|
||||
render json: @records.includes(my_module: { experiment: { project: :team } }),
|
||||
each_serializer: GlobalSearch::ResultSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: results.try(:next_page)
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'protocols'
|
||||
search_protocols
|
||||
results = if params[:preview] == 'true'
|
||||
@protocol_results.take(4)
|
||||
else
|
||||
@protocol_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
paginate_records
|
||||
|
||||
render json: results,
|
||||
render json: @records,
|
||||
each_serializer: GlobalSearch::ProtocolSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: (results.next_page if results.respond_to?(:next_page))
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'label_templates'
|
||||
|
|
@ -136,50 +103,38 @@ class SearchController < ApplicationController
|
|||
|
||||
@label_template_search_count = fetch_cached_count(LabelTemplate)
|
||||
search_label_templates
|
||||
results = if params[:preview] == 'true'
|
||||
@label_template_results.take(4)
|
||||
else
|
||||
@label_template_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
paginate_records
|
||||
|
||||
render json: results,
|
||||
render json: @records,
|
||||
each_serializer: GlobalSearch::LabelTemplateSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: (results.next_page if results.respond_to?(:next_page))
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'repository_rows'
|
||||
@repository_row_search_count = fetch_cached_count(RepositoryRow)
|
||||
search_repository_rows
|
||||
results = if params[:preview] == 'true'
|
||||
@repository_row_results.take(4)
|
||||
else
|
||||
@repository_row_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
paginate_records
|
||||
|
||||
render json: results,
|
||||
render json: @records,
|
||||
each_serializer: GlobalSearch::RepositoryRowSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: (results.next_page if results.respond_to?(:next_page))
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
when 'assets'
|
||||
@asset_search_count = fetch_cached_count(Asset)
|
||||
search_assets
|
||||
includes = [{ step: { protocol: { my_module: :experiment } } }, { result: { my_module: :experiment } }, :team]
|
||||
results = if params[:preview] == 'true'
|
||||
@asset_results.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@asset_results.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
paginate_records
|
||||
|
||||
render json: results.includes(includes),
|
||||
render json: @records.includes(includes),
|
||||
each_serializer: GlobalSearch::AssetSerializer,
|
||||
meta: {
|
||||
total: @search_count,
|
||||
next_page: (results.next_page if results.respond_to?(:next_page))
|
||||
next_page: @records.try(:next_page)
|
||||
}
|
||||
return
|
||||
end
|
||||
|
|
@ -220,16 +175,8 @@ class SearchController < ApplicationController
|
|||
def load_vars
|
||||
query = (params.fetch(:q) { '' }).strip
|
||||
@filters = params[:filters]
|
||||
@include_archived = if @filters.present?
|
||||
@filters[:include_archived] == 'true'
|
||||
else
|
||||
true
|
||||
end
|
||||
@teams = if @filters.present?
|
||||
@filters[:teams]&.values || current_user.teams
|
||||
else
|
||||
current_user.teams
|
||||
end
|
||||
@include_archived = @filters.blank? || @filters[:include_archived] == 'true'
|
||||
@teams = (@filters.present? && @filters[:teams]&.values) || current_user.teams
|
||||
@display_query = query
|
||||
|
||||
splited_query = query.split
|
||||
|
|
@ -257,16 +204,16 @@ class SearchController < ApplicationController
|
|||
end
|
||||
|
||||
def search_by_name(model, options={})
|
||||
records = model.search(current_user,
|
||||
@include_archived,
|
||||
@search_query,
|
||||
nil,
|
||||
teams: @teams,
|
||||
users: @users,
|
||||
options: options)
|
||||
@records = model.search(current_user,
|
||||
@include_archived,
|
||||
@search_query,
|
||||
nil,
|
||||
teams: @teams,
|
||||
users: @users,
|
||||
options: options)
|
||||
|
||||
records = filter_records(records, model) if @filters.present?
|
||||
sort_records(records)
|
||||
filter_records(model) if @filters.present?
|
||||
sort_records
|
||||
end
|
||||
|
||||
def count_by_name(model, options = {})
|
||||
|
|
@ -289,121 +236,119 @@ class SearchController < ApplicationController
|
|||
end
|
||||
|
||||
def search_projects
|
||||
@project_results = Project.none
|
||||
@project_results = search_by_name(Project) if @project_search_count.positive?
|
||||
@records = Project.none
|
||||
search_by_name(Project) if @project_search_count.positive?
|
||||
@search_count = @project_search_count
|
||||
end
|
||||
|
||||
def search_project_folders
|
||||
@project_folder_results = ProjectFolder.none
|
||||
@project_folder_results = search_by_name(ProjectFolder) if @project_folder_search_count.positive?
|
||||
@records = ProjectFolder.none
|
||||
@records = search_by_name(ProjectFolder) if @project_folder_search_count.positive?
|
||||
@search_count = @project_folder_search_count
|
||||
end
|
||||
|
||||
def search_experiments
|
||||
@experiment_results = Experiment.none
|
||||
@experiment_results = search_by_name(Experiment) if @experiment_search_count.positive?
|
||||
@records = Experiment.none
|
||||
@records = search_by_name(Experiment) if @experiment_search_count.positive?
|
||||
@search_count = @experiment_search_count
|
||||
end
|
||||
|
||||
def search_modules
|
||||
@module_results = MyModule.none
|
||||
@module_results = search_by_name(MyModule) if @module_search_count.positive?
|
||||
@records = MyModule.none
|
||||
@records = search_by_name(MyModule) if @module_search_count.positive?
|
||||
@search_count = @module_search_count
|
||||
end
|
||||
|
||||
def search_module_protocols
|
||||
@module_protocol_results = search_by_name(Protocol, { in_repository: false })
|
||||
@search_count = @module_protocol_results.count
|
||||
@records = search_by_name(Protocol, { in_repository: false })
|
||||
@search_count = @records.count
|
||||
end
|
||||
|
||||
def search_results
|
||||
@result_results = Result.none
|
||||
@result_results = search_by_name(Result) if @result_search_count.positive?
|
||||
@records = Result.none
|
||||
@records = search_by_name(Result) if @result_search_count.positive?
|
||||
@search_count = @result_search_count
|
||||
end
|
||||
|
||||
def search_reports
|
||||
@report_results = Report.none
|
||||
@report_results = search_by_name(Report) if @report_search_count.positive?
|
||||
@records = Report.none
|
||||
@records = search_by_name(Report) if @report_search_count.positive?
|
||||
@search_count = @report_search_count
|
||||
end
|
||||
|
||||
def search_protocols
|
||||
@protocol_results = search_by_name(Protocol, { in_repository: true })
|
||||
@search_count = @protocol_results.count
|
||||
@records = search_by_name(Protocol, { in_repository: true })
|
||||
@search_count = @records.count
|
||||
end
|
||||
|
||||
def search_label_templates
|
||||
@label_template_results = LabelTemplate.none
|
||||
@label_template_results = search_by_name(LabelTemplate) if @label_template_search_count.positive?
|
||||
@records = LabelTemplate.none
|
||||
@records = search_by_name(LabelTemplate) if @label_template_search_count.positive?
|
||||
@search_count = @label_template_search_count
|
||||
end
|
||||
|
||||
def search_steps
|
||||
@step_results = []
|
||||
@step_results = search_by_name(Step) if @step_search_count.positive?
|
||||
@records = []
|
||||
@records = search_by_name(Step) if @step_search_count.positive?
|
||||
@search_count = @step_search_count
|
||||
end
|
||||
|
||||
def search_repository_rows
|
||||
@repository_row_results = RepositoryRow.none
|
||||
@repository_row_results = search_by_name(RepositoryRow) if @repository_row_search_count.positive?
|
||||
@records = RepositoryRow.none
|
||||
@records = search_by_name(RepositoryRow) if @repository_row_search_count.positive?
|
||||
@search_count = @repository_row_search_count
|
||||
end
|
||||
|
||||
def search_assets
|
||||
@asset_results = Asset.none
|
||||
@asset_results = search_by_name(Asset) if @asset_search_count.positive?
|
||||
@records = Asset.none
|
||||
@records = search_by_name(Asset) if @asset_search_count.positive?
|
||||
@search_count = @asset_search_count
|
||||
end
|
||||
|
||||
def filter_records(records, model)
|
||||
model_name = model.model_name.collection
|
||||
if @filters[:created_at].present?
|
||||
if @filters[:created_at][:on].present?
|
||||
from_date = Time.zone.parse(@filters[:created_at][:on]).beginning_of_day.utc
|
||||
to_date = Time.zone.parse(@filters[:created_at][:on]).end_of_day.utc
|
||||
else
|
||||
from_date = Time.zone.parse(@filters[:created_at][:from])
|
||||
to_date = Time.zone.parse(@filters[:created_at][:to])
|
||||
end
|
||||
|
||||
records = records.where("#{model_name}.created_at >= ?", from_date)
|
||||
records = records.where("#{model_name}.created_at <= ?", to_date)
|
||||
end
|
||||
|
||||
if @filters[:updated_at].present?
|
||||
if @filters[:updated_at][:on].present?
|
||||
from_date = Time.zone.parse(@filters[:updated_at][:on]).beginning_of_day.utc
|
||||
to_date = Time.zone.parse(@filters[:updated_at][:on]).end_of_day.utc
|
||||
else
|
||||
from_date = Time.zone.parse(@filters[:updated_at][:from])
|
||||
to_date = Time.zone.parse(@filters[:updated_at][:to])
|
||||
end
|
||||
|
||||
records = records.where("#{model_name}.updated_at >= ?", from_date)
|
||||
records = records.where("#{model_name}.updated_at <= ?", to_date)
|
||||
end
|
||||
|
||||
if @filters[:users].present?
|
||||
records = records.joins("INNER JOIN activities ON #{model_name}.id = activities.subject_id
|
||||
AND activities.subject_type= '#{model.name}'")
|
||||
.where('activities.owner_id': @filters[:users]&.values)
|
||||
end
|
||||
records
|
||||
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
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
def paginate_records
|
||||
@records = if params[:preview] == 'true'
|
||||
@records.limit(Constants::GLOBAL_SEARCH_PREVIEW_LIMIT)
|
||||
else
|
||||
@records.page(params[:page]).per(Constants::SEARCH_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
elsif @filters[attribute][:from].present? && @filters[attribute][:to].present?
|
||||
from_date = Time.zone.parse(@filters[attribute][:from])
|
||||
to_date = Time.zone.parse(@filters[attribute][:to])
|
||||
end
|
||||
|
||||
@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!(model)
|
||||
@records = @records.joins("INNER JOIN activities ON #{model.model_name.collection}.id = activities.subject_id
|
||||
AND activities.subject_type= '#{model.name}'")
|
||||
.where('activities.owner_id': @filters[:users]&.values)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class Asset < ApplicationRecord
|
|||
|
||||
assets_in_inventories = Asset.joins(
|
||||
repository_cell: { repository_column: :repository }
|
||||
).where(repositories: { team_id: teams }).pluck(:id)
|
||||
).where(repositories: { team: teams }).pluck(:id)
|
||||
|
||||
assets =
|
||||
Asset.distinct
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module SearchableModel
|
|||
scope :where_attributes_like, lambda { |attributes, query, options = {}|
|
||||
return unless query
|
||||
|
||||
attrs = convert_input(attributes)
|
||||
attrs = normalized_attributes(attributes)
|
||||
|
||||
if options[:whole_word].to_s == 'true' ||
|
||||
options[:whole_phrase].to_s == 'true' ||
|
||||
|
|
@ -102,7 +102,7 @@ module SearchableModel
|
|||
scope :where_attributes_like_boolean, lambda { |attributes, query, options = {}|
|
||||
return unless query
|
||||
|
||||
attrs = convert_input(attributes)
|
||||
attrs = normalized_attributes(attributes)
|
||||
where_array = []
|
||||
value_array = {}
|
||||
current_phrase = ''
|
||||
|
|
@ -146,7 +146,7 @@ module SearchableModel
|
|||
where(where_array.join[0..-5], value_array)
|
||||
}
|
||||
|
||||
def self.convert_input(attributes)
|
||||
def self.normalized_attributes(attributes)
|
||||
attrs = []
|
||||
if attributes.blank?
|
||||
# Do nothing in this case
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ class Step < ApplicationRecord
|
|||
.pluck(:id)
|
||||
|
||||
Step.distinct
|
||||
.where(protocol_id: protocol_ids + my_module_ids)
|
||||
.left_outer_joins(:step_texts)
|
||||
.where(protocol_id: protocol_ids + my_module_ids)
|
||||
.where(steps: { protocol_id: protocol_ids })
|
||||
.where_attributes_like_boolean(['steps.name', 'step_texts.text'], query, options)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue