165 lines
4.1 KiB
Ruby
165 lines
4.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
# Holds the contextual data used by navbar search component to
|
|
# determine the search scope, whether to search for code, or if
|
|
# a search should target snippets.
|
|
#
|
|
# Use the SearchContext::Builder to create an instance of this class
|
|
class SearchContext
|
|
attr_accessor :project, :project_metadata, :ref,
|
|
:group, :group_metadata,
|
|
:snippets,
|
|
:scope, :search_url
|
|
|
|
def initialize
|
|
@ref = nil
|
|
@project = nil
|
|
@project_metadata = {}
|
|
@group = nil
|
|
@group_metadata = {}
|
|
@snippets = []
|
|
@scope = nil
|
|
@search_url = nil
|
|
end
|
|
|
|
def for_project?
|
|
project.present? && project.persisted?
|
|
end
|
|
|
|
def for_group?
|
|
group.present? && group.persisted?
|
|
end
|
|
|
|
def for_snippets?
|
|
snippets.any?
|
|
end
|
|
|
|
def code_search?
|
|
project.present? && scope.nil?
|
|
end
|
|
|
|
class Builder
|
|
def initialize(view_context)
|
|
@view_context = view_context
|
|
@snippets = []
|
|
end
|
|
|
|
def with_snippet(snippet)
|
|
@snippets << snippet
|
|
|
|
self
|
|
end
|
|
|
|
def with_project(project)
|
|
@project = project
|
|
with_group(project&.group)
|
|
|
|
self
|
|
end
|
|
|
|
def with_group(group)
|
|
@group = group
|
|
|
|
self
|
|
end
|
|
|
|
def with_ref(ref)
|
|
@ref = ref
|
|
|
|
self
|
|
end
|
|
|
|
def build!
|
|
SearchContext.new.tap do |context|
|
|
context.project = @project
|
|
context.group = @group
|
|
context.ref = @ref
|
|
context.snippets = @snippets.dup
|
|
context.scope = search_scope
|
|
context.search_url = search_url
|
|
context.group_metadata = group_search_metadata(@group)
|
|
context.project_metadata = project_search_metadata(@project)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
attr_accessor :view_context
|
|
|
|
def project_search_metadata(project)
|
|
return {} unless project
|
|
|
|
{
|
|
project_path: project.path,
|
|
name: project.name,
|
|
issues_path: view_context.project_issues_path(project),
|
|
mr_path: view_context.project_merge_requests_path(project),
|
|
issues_disabled: !project.issues_enabled?
|
|
}
|
|
end
|
|
|
|
def group_search_metadata(group)
|
|
return {} unless group
|
|
|
|
{
|
|
group_path: group.path,
|
|
name: group.name,
|
|
issues_path: view_context.issues_group_path(group),
|
|
mr_path: view_context.merge_requests_group_path(group)
|
|
}
|
|
end
|
|
|
|
def search_url
|
|
if @project.present?
|
|
view_context.search_path(project_id: @project.id)
|
|
elsif @group.present?
|
|
view_context.search_path(group_id: @group.id)
|
|
else
|
|
view_context.search_path
|
|
end
|
|
end
|
|
|
|
def search_scope
|
|
if view_context.current_controller?(:issues)
|
|
'issues'
|
|
elsif view_context.current_controller?(:merge_requests)
|
|
'merge_requests'
|
|
elsif view_context.current_controller?(:wikis)
|
|
'wiki_blobs'
|
|
elsif view_context.current_controller?(:commits)
|
|
'commits'
|
|
elsif view_context.current_controller?(:groups)
|
|
if %w(issues merge_requests).include?(view_context.controller.action_name)
|
|
view_context.controller.action_name
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
module ControllerConcern
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
helper_method :search_context
|
|
end
|
|
|
|
# rubocop:disable Gitlab/ModuleWithInstanceVariables
|
|
#
|
|
# Introspect the current controller's assignments and
|
|
# and builds the proper SearchContext object for it.
|
|
def search_context
|
|
builder = Builder.new(view_context)
|
|
|
|
builder.with_snippet(@snippet) if @snippet.present?
|
|
@snippets.each(&builder.method(:with_snippet)) if @snippets.present?
|
|
builder.with_project(@project) if @project.present? && @project.persisted?
|
|
builder.with_group(@group) if @group.present? && @group.persisted?
|
|
builder.with_ref(@ref) if @ref.present?
|
|
|
|
builder.build!
|
|
end
|
|
# rubocop:enable Gitlab/ModuleWithInstanceVariables
|
|
end
|
|
end
|
|
end
|