From 84dd5eaa70d996be2834ee6fd42a97ccaf94e018 Mon Sep 17 00:00:00 2001 From: sboursen-scinote Date: Wed, 3 Apr 2024 00:55:09 +0200 Subject: [PATCH] Implement global search results component for inventory items [SCI-10476] --- app/controllers/search_controller.rb | 22 +++++++++ .../global_search/groups/repository_rows.vue | 48 ++++++++++++++++++- app/models/repository_row.rb | 29 +++++++++++ .../repository_row_serializer.rb | 39 +++++++++++++++ config/locales/en.yml | 1 + 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 app/serializers/global_search/repository_row_serializer.rb diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index f7f281563..ceb4377c6 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -73,6 +73,22 @@ class SearchController < ApplicationController next_page: (results.next_page if results.respond_to?(: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 + + render json: results, + each_serializer: GlobalSearch::RepositoryRowSerializer, + meta: { + total: @search_count, + next_page: (results.next_page if results.respond_to?(:next_page)) + } + return end #@search_id = params[:search_id] ? params[:search_id] : generate_search_id @@ -372,6 +388,12 @@ class SearchController < ApplicationController @search_count = current_repository_search_count end + def search_repository_rows + @repository_row_results = [] + @repository_row_results = search_by_name(RepositoryRow) if @repository_row_search_count.positive? + @search_count = @repository_row_search_count + end + def search_assets @asset_results = [] @asset_results = search_by_name(Asset) if @asset_search_count.positive? diff --git a/app/javascript/vue/global_search/groups/repository_rows.vue b/app/javascript/vue/global_search/groups/repository_rows.vue index 7b37e4b5e..e7bbf34e6 100644 --- a/app/javascript/vue/global_search/groups/repository_rows.vue +++ b/app/javascript/vue/global_search/groups/repository_rows.vue @@ -3,12 +3,58 @@

{{ i18n.t('search.index.inventory_items') }} + [{{ total }}]

+
+
+ +
+
+ +
+
diff --git a/app/models/repository_row.rb b/app/models/repository_row.rb index 0c38d7f2f..624175566 100644 --- a/app/models/repository_row.rb +++ b/app/models/repository_row.rb @@ -120,6 +120,35 @@ class RepositoryRow < ApplicationRecord where(repository: Repository.viewable_by_user(user, teams)) end + def self.search(user, + include_archived, + query = nil, + page = 1, + _current_team = nil, + options = {}) + + searchable_row_fields = [RepositoryRow::PREFIXED_ID_SQL, 'repository_rows.name', 'users.full_name'] + repositories = Repository.search(user).pluck(:id) + + new_query = + RepositoryRow + .joins(:repository, :created_by) + .where(repository_id: repositories) + .distinct + .where_attributes_like( + searchable_row_fields, query, options + ) + + new_query = new_query.active unless include_archived + + # Show all results if needed + if page == Constants::SEARCH_NO_LIMIT + new_query + else + new_query.limit(Constants::SEARCH_LIMIT).offset((page - 1) * Constants::SEARCH_LIMIT) + end + end + def self.filter_by_teams(teams = []) return self if teams.blank? diff --git a/app/serializers/global_search/repository_row_serializer.rb b/app/serializers/global_search/repository_row_serializer.rb new file mode 100644 index 000000000..49011ff90 --- /dev/null +++ b/app/serializers/global_search/repository_row_serializer.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module GlobalSearch + class RepositoryRowSerializer < ActiveModel::Serializer + include Rails.application.routes.url_helpers + + attributes :id, :name, :code, :created_at, :created_by, :team, :repository, :archived, :url + + def team + { + name: object.team.name, + url: repository_path(object.repository) + } + end + + def created_by + { + name: object.created_by.name, + avatar_url: avatar_path(object.created_by, :icon_small) + } + end + + def created_at + I18n.l(object.created_at, format: :full_date) + end + + def repository + { + name: object.repository.name, + url: repository_path(object.repository) + } + end + + def url + # switch to repository_repository_rows_path when inventory items page is implemented + repository_path(object.repository) + end + end +end diff --git a/config/locales/en.yml b/config/locales/en.yml index 62e92ba04..e9d881f53 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -453,6 +453,7 @@ en: protocol_templates: "Protocol templates" label_templates: "Label templates" reports: "Reports" + repository: "Inventory" more_search_options: "More search options" clear_filters: "Clear filters" id: "ID"