mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-11-01 00:56:05 +08:00
Implement quick search backend [SCI-10246]
This commit is contained in:
parent
ba5eca7d8e
commit
ae5cebe7d7
7 changed files with 52 additions and 18 deletions
|
|
@ -114,23 +114,33 @@ class SearchController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def quick
|
def quick
|
||||||
results = [
|
results = if params[:filter].present?
|
||||||
Project.first,
|
object_quick_search(params[:filter].singularize,
|
||||||
Experiment.first,
|
search_by_id: Constants::QUICK_SEARCH_SEARCHABLE_BY_NAME
|
||||||
MyModule.first,
|
.exclude?(params[:filter].singularize))
|
||||||
Protocol.first,
|
else
|
||||||
RepositoryRow.first,
|
Constants::QUICK_SEARCH_SEARCHABLE_OBJECTS.filter_map do |object|
|
||||||
Result.first,
|
next if object == 'label_template' && !LabelTemplate.enabled?
|
||||||
Step.first,
|
|
||||||
Report.first,
|
object_quick_search(object, search_by_id: Constants::QUICK_SEARCH_SEARCHABLE_BY_NAME.exclude?(object))
|
||||||
LabelTemplate.first
|
end.flatten.sort_by(&:updated_at).reverse.take(Constants::QUICK_SEARCH_LIMIT)
|
||||||
].compact
|
end
|
||||||
|
|
||||||
render json: results, each_serializer: QuickSearchSerializer
|
render json: results, each_serializer: QuickSearchSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def object_quick_search(class_name, search_by_id: true)
|
||||||
|
search_method = class_name.to_s.camelize.constantize.method(search_by_id ? :search_by_name_and_id : :search_by_name)
|
||||||
|
|
||||||
|
search_method.call(current_user,
|
||||||
|
current_team,
|
||||||
|
params[:query],
|
||||||
|
limit: Constants::QUICK_SEARCH_LIMIT)
|
||||||
|
.order(updated_at: :desc)
|
||||||
|
end
|
||||||
|
|
||||||
def load_vars
|
def load_vars
|
||||||
query = (params.fetch(:q) { '' }).strip
|
query = (params.fetch(:q) { '' }).strip
|
||||||
@search_category = params[:category] || ''
|
@search_category = params[:category] || ''
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,9 @@ export default {
|
||||||
const breadcrumbs = attributes.breadcrumbs.map((breadcrumb) => breadcrumb.name);
|
const breadcrumbs = attributes.breadcrumbs.map((breadcrumb) => breadcrumb.name);
|
||||||
breadcrumbs.pop();
|
breadcrumbs.pop();
|
||||||
breadcrumbs.shift();
|
breadcrumbs.shift();
|
||||||
breadcrumbs.push(`ID: ${attributes.code}`);
|
if (attributes.code) {
|
||||||
|
breadcrumbs.push(`ID: ${attributes.code}`);
|
||||||
|
}
|
||||||
return breadcrumbs;
|
return breadcrumbs;
|
||||||
},
|
},
|
||||||
setQuery(query) {
|
setQuery(query) {
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ module SearchableByNameModel
|
||||||
|
|
||||||
sql_q = sql_q.where(id: viewable_by_user(user, teams))
|
sql_q = sql_q.where(id: viewable_by_user(user, teams))
|
||||||
|
|
||||||
sql_q.limit(Constants::SEARCH_LIMIT)
|
sql_q.limit(options[:limit] || Constants::SEARCH_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.search_by_name_and_id(user, teams = [], query = nil)
|
def self.search_by_name_and_id(user, teams = [], query = nil, options = {})
|
||||||
return if user.blank? || teams.blank?
|
return if user.blank? || teams.blank?
|
||||||
|
|
||||||
sanitized_query = ActiveRecord::Base.sanitize_sql_like(query.to_s)
|
sanitized_query = ActiveRecord::Base.sanitize_sql_like(query.to_s)
|
||||||
|
|
@ -34,7 +34,7 @@ module SearchableByNameModel
|
||||||
"%#{sanitized_query}%", "%#{sanitized_query}%"
|
"%#{sanitized_query}%", "%#{sanitized_query}%"
|
||||||
)
|
)
|
||||||
|
|
||||||
sql_q.limit(Constants::SEARCH_LIMIT)
|
sql_q.limit(options[:limit] || Constants::SEARCH_LIMIT)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# rubocop:enable Metrics/BlockLength
|
# rubocop:enable Metrics/BlockLength
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
class LabelTemplate < ApplicationRecord
|
class LabelTemplate < ApplicationRecord
|
||||||
include SearchableModel
|
include SearchableModel
|
||||||
|
include SearchableByNameModel
|
||||||
|
|
||||||
belongs_to :team
|
belongs_to :team
|
||||||
belongs_to :created_by, class_name: 'User', optional: true
|
belongs_to :created_by, class_name: 'User', optional: true
|
||||||
|
|
@ -17,6 +18,17 @@ class LabelTemplate < ApplicationRecord
|
||||||
|
|
||||||
scope :default, -> { where(default: true) }
|
scope :default, -> { where(default: true) }
|
||||||
|
|
||||||
|
def self.viewable_by_user(user, teams)
|
||||||
|
joins("INNER JOIN user_assignments team_user_assignments
|
||||||
|
ON team_user_assignments.assignable_id = label_templates.team_id
|
||||||
|
AND team_user_assignments.assignable_type = 'Team'
|
||||||
|
AND team_user_assignments.user_id = #{user.id}
|
||||||
|
INNER JOIN user_roles team_user_roles
|
||||||
|
ON team_user_roles.id = team_user_assignments.user_role_id
|
||||||
|
AND team_user_roles.permissions @> ARRAY['#{TeamPermissions::LABEL_TEMPLATES_READ}']::varchar[]")
|
||||||
|
.where(team: teams)
|
||||||
|
end
|
||||||
|
|
||||||
def self.enabled?
|
def self.enabled?
|
||||||
ApplicationSettings.instance.values['label_templates_enabled'] == true
|
ApplicationSettings.instance.values['label_templates_enabled'] == true
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,12 @@ class ProjectFolder < ApplicationRecord
|
||||||
|
|
||||||
scope :top_level, -> { where(parent_folder: nil) }
|
scope :top_level, -> { where(parent_folder: nil) }
|
||||||
|
|
||||||
|
def self.viewable_by_user(user, teams)
|
||||||
|
joins(team: :users)
|
||||||
|
.where(teams: { user_assignments: { user: user } })
|
||||||
|
.where(team: teams)
|
||||||
|
end
|
||||||
|
|
||||||
def self.search(user, _include_archived, query = nil, page = 1, current_team = nil, options = {})
|
def self.search(user, _include_archived, query = nil, page = 1, current_team = nil, options = {})
|
||||||
new_query = if current_team
|
new_query = if current_team
|
||||||
current_team.project_folders.where_attributes_like(:name, query, options)
|
current_team.project_folders.where_attributes_like(:name, query, options)
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,7 @@ class QuickSearchSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def code
|
def code
|
||||||
@object.code
|
@object.code unless @object.is_a?(ProjectFolder) || object.is_a?(Result) || object.is_a?(LabelTemplate)
|
||||||
rescue StandardError
|
|
||||||
@object.id
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def updated_at
|
def updated_at
|
||||||
|
|
|
||||||
|
|
@ -443,6 +443,12 @@ class Constants
|
||||||
MIN_SCINOTE_EDIT_VERSION = ENV['MIN_SCINOTE_EDIT_VERSION'].freeze
|
MIN_SCINOTE_EDIT_VERSION = ENV['MIN_SCINOTE_EDIT_VERSION'].freeze
|
||||||
MAX_SCINOTE_EDIT_VERSION = ENV['MAX_SCINOTE_EDIT_VERSION'].freeze
|
MAX_SCINOTE_EDIT_VERSION = ENV['MAX_SCINOTE_EDIT_VERSION'].freeze
|
||||||
|
|
||||||
|
# quick search
|
||||||
|
QUICK_SEARCH_LIMIT = 5
|
||||||
|
QUICK_SEARCH_SEARCHABLE_OBJECTS = %w(project experiment my_module protocol repository_row
|
||||||
|
report project_folder result label_template).freeze
|
||||||
|
QUICK_SEARCH_SEARCHABLE_BY_NAME = %w(project_folder result label_template).freeze
|
||||||
|
|
||||||
# ) \ / (
|
# ) \ / (
|
||||||
# /|\ )\_/( /|\
|
# /|\ )\_/( /|\
|
||||||
# * / | \ (/\|/\) / | \ *
|
# * / | \ (/\|/\) / | \ *
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue