summaryrefslogtreecommitdiff
path: root/app/finders
diff options
context:
space:
mode:
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/alert_management/alerts_finder.rb55
-rw-r--r--app/finders/artifacts_finder.rb24
-rw-r--r--app/finders/ci/daily_build_group_report_results_finder.rb37
-rw-r--r--app/finders/ci/job_artifacts_finder.rb26
-rw-r--r--app/finders/clusters/knative_services_finder.rb1
-rw-r--r--app/finders/container_repositories_finder.rb13
-rw-r--r--app/finders/design_management/designs_finder.rb57
-rw-r--r--app/finders/design_management/versions_finder.rb58
-rw-r--r--app/finders/freeze_periods_finder.rb14
-rw-r--r--app/finders/group_members_finder.rb2
-rw-r--r--app/finders/issuable_finder.rb133
-rw-r--r--app/finders/issuable_finder/params.rb2
-rw-r--r--app/finders/issues_finder/params.rb2
-rw-r--r--app/finders/members_finder.rb16
-rw-r--r--app/finders/metrics/users_starred_dashboards_finder.rb35
-rw-r--r--app/finders/projects/serverless/functions_finder.rb1
-rw-r--r--app/finders/projects_finder.rb4
-rw-r--r--app/finders/releases_finder.rb20
-rw-r--r--app/finders/todos_finder.rb2
19 files changed, 422 insertions, 80 deletions
diff --git a/app/finders/alert_management/alerts_finder.rb b/app/finders/alert_management/alerts_finder.rb
new file mode 100644
index 00000000000..cb35be43c15
--- /dev/null
+++ b/app/finders/alert_management/alerts_finder.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module AlertManagement
+ class AlertsFinder
+ # @return [Hash<Integer,Integer>] Mapping of status id to count
+ # ex) { 0: 6, ...etc }
+ def self.counts_by_status(current_user, project, params = {})
+ new(current_user, project, params).execute.counts_by_status
+ end
+
+ def initialize(current_user, project, params)
+ @current_user = current_user
+ @project = project
+ @params = params
+ end
+
+ def execute
+ return AlertManagement::Alert.none unless authorized?
+
+ collection = project.alert_management_alerts
+ collection = by_status(collection)
+ collection = by_search(collection)
+ collection = by_iid(collection)
+ sort(collection)
+ end
+
+ private
+
+ attr_reader :current_user, :project, :params
+
+ def by_iid(collection)
+ return collection unless params[:iid]
+
+ collection.for_iid(params[:iid])
+ end
+
+ def by_status(collection)
+ values = AlertManagement::Alert::STATUSES.values & Array(params[:status])
+
+ values.present? ? collection.for_status(values) : collection
+ end
+
+ def by_search(collection)
+ params[:search].present? ? collection.search(params[:search]) : collection
+ end
+
+ def sort(collection)
+ params[:sort] ? collection.sort_by_attribute(params[:sort]) : collection
+ end
+
+ def authorized?
+ Ability.allowed?(current_user, :read_alert_management_alert, project)
+ end
+ end
+end
diff --git a/app/finders/artifacts_finder.rb b/app/finders/artifacts_finder.rb
deleted file mode 100644
index 81c5168d782..00000000000
--- a/app/finders/artifacts_finder.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-class ArtifactsFinder
- def initialize(project, params = {})
- @project = project
- @params = params
- end
-
- def execute
- artifacts = @project.job_artifacts
-
- sort(artifacts)
- end
-
- private
-
- def sort_key
- @params[:sort] || 'created_desc'
- end
-
- def sort(artifacts)
- artifacts.order_by(sort_key)
- end
-end
diff --git a/app/finders/ci/daily_build_group_report_results_finder.rb b/app/finders/ci/daily_build_group_report_results_finder.rb
new file mode 100644
index 00000000000..3c3c24c1479
--- /dev/null
+++ b/app/finders/ci/daily_build_group_report_results_finder.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Ci
+ class DailyBuildGroupReportResultsFinder
+ include Gitlab::Allowable
+
+ def initialize(current_user:, project:, ref_path:, start_date:, end_date:, limit: nil)
+ @current_user = current_user
+ @project = project
+ @ref_path = ref_path
+ @start_date = start_date
+ @end_date = end_date
+ @limit = limit
+ end
+
+ def execute
+ return none unless can?(current_user, :download_code, project)
+
+ Ci::DailyBuildGroupReportResult.recent_results(
+ {
+ project_id: project,
+ ref_path: ref_path,
+ date: start_date..end_date
+ },
+ limit: @limit
+ )
+ end
+
+ private
+
+ attr_reader :current_user, :project, :ref_path, :start_date, :end_date
+
+ def none
+ Ci::DailyBuildGroupReportResult.none
+ end
+ end
+end
diff --git a/app/finders/ci/job_artifacts_finder.rb b/app/finders/ci/job_artifacts_finder.rb
new file mode 100644
index 00000000000..808c159ced1
--- /dev/null
+++ b/app/finders/ci/job_artifacts_finder.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Ci
+ class JobArtifactsFinder
+ def initialize(project, params = {})
+ @project = project
+ @params = params
+ end
+
+ def execute
+ artifacts = @project.job_artifacts
+
+ sort(artifacts)
+ end
+
+ private
+
+ def sort_key
+ @params[:sort] || 'created_desc'
+ end
+
+ def sort(artifacts)
+ artifacts.order_by(sort_key)
+ end
+ end
+end
diff --git a/app/finders/clusters/knative_services_finder.rb b/app/finders/clusters/knative_services_finder.rb
index 71cebe4495e..af8c42f672f 100644
--- a/app/finders/clusters/knative_services_finder.rb
+++ b/app/finders/clusters/knative_services_finder.rb
@@ -11,6 +11,7 @@ module Clusters
}.freeze
self.reactive_cache_key = ->(finder) { finder.model_name }
+ self.reactive_cache_work_type = :external_dependency
self.reactive_cache_worker_finder = ->(_id, *cache_args) { from_cache(*cache_args) }
attr_reader :cluster, :environment
diff --git a/app/finders/container_repositories_finder.rb b/app/finders/container_repositories_finder.rb
index 34921df840b..5109efb361b 100644
--- a/app/finders/container_repositories_finder.rb
+++ b/app/finders/container_repositories_finder.rb
@@ -3,17 +3,18 @@
class ContainerRepositoriesFinder
VALID_SUBJECTS = [Group, Project].freeze
- def initialize(user:, subject:)
+ def initialize(user:, subject:, params: {})
@user = user
@subject = subject
+ @params = params
end
def execute
raise ArgumentError, "invalid subject_type" unless valid_subject_type?
return unless authorized?
- return project_repositories if @subject.is_a?(Project)
- return group_repositories if @subject.is_a?(Group)
+ repositories = @subject.is_a?(Project) ? project_repositories : group_repositories
+ filter_by_image_name(repositories)
end
private
@@ -32,6 +33,12 @@ class ContainerRepositoriesFinder
ContainerRepository.for_group_and_its_subgroups(@subject)
end
+ def filter_by_image_name(repositories)
+ return repositories unless @params[:name]
+
+ repositories.search_by_name(@params[:name])
+ end
+
def authorized?
Ability.allowed?(@user, :read_container_image, @subject)
end
diff --git a/app/finders/design_management/designs_finder.rb b/app/finders/design_management/designs_finder.rb
new file mode 100644
index 00000000000..10f95520d1e
--- /dev/null
+++ b/app/finders/design_management/designs_finder.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module DesignManagement
+ class DesignsFinder
+ include Gitlab::Allowable
+
+ # Params:
+ # ids: integer[]
+ # filenames: string[]
+ # visible_at_version: ?version
+ # filenames: String[]
+ def initialize(issue, current_user, params = {})
+ @issue = issue
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ items = init_collection
+
+ items = by_visible_at_version(items)
+ items = by_filename(items)
+ items = by_id(items)
+
+ items
+ end
+
+ private
+
+ attr_reader :issue, :current_user, :params
+
+ def init_collection
+ return ::DesignManagement::Design.none unless can?(current_user, :read_design, issue)
+
+ issue.designs
+ end
+
+ # Returns all designs that existed at a particular design version
+ def by_visible_at_version(items)
+ items.visible_at_version(params[:visible_at_version])
+ end
+
+ def by_filename(items)
+ return items if params[:filenames].nil?
+ return ::DesignManagement::Design.none if params[:filenames].empty?
+
+ items.with_filename(params[:filenames])
+ end
+
+ def by_id(items)
+ return items if params[:ids].nil?
+ return ::DesignManagement::Design.none if params[:ids].empty?
+
+ items.id_in(params[:ids])
+ end
+ end
+end
diff --git a/app/finders/design_management/versions_finder.rb b/app/finders/design_management/versions_finder.rb
new file mode 100644
index 00000000000..c4aefd3078e
--- /dev/null
+++ b/app/finders/design_management/versions_finder.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module DesignManagement
+ class VersionsFinder
+ attr_reader :design_or_collection, :current_user, :params
+
+ # The `design_or_collection` argument should be either a:
+ #
+ # - DesignManagement::Design, or
+ # - DesignManagement::DesignCollection
+ #
+ # The object will have `#versions` called on it to set up the
+ # initial scope of the versions.
+ #
+ # valid params:
+ # - earlier_or_equal_to: Version
+ # - sha: String
+ # - version_id: Integer
+ #
+ def initialize(design_or_collection, current_user, params = {})
+ @design_or_collection = design_or_collection
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ unless Ability.allowed?(current_user, :read_design, design_or_collection)
+ return ::DesignManagement::Version.none
+ end
+
+ items = design_or_collection.versions
+ items = by_earlier_or_equal_to(items)
+ items = by_sha(items)
+ items = by_version_id(items)
+ items.ordered
+ end
+
+ private
+
+ def by_earlier_or_equal_to(items)
+ return items unless params[:earlier_or_equal_to]
+
+ items.earlier_or_equal_to(params[:earlier_or_equal_to])
+ end
+
+ def by_version_id(items)
+ return items unless params[:version_id]
+
+ items.id_in(params[:version_id])
+ end
+
+ def by_sha(items)
+ return items unless params[:sha]
+
+ items.by_sha(params[:sha])
+ end
+ end
+end
diff --git a/app/finders/freeze_periods_finder.rb b/app/finders/freeze_periods_finder.rb
new file mode 100644
index 00000000000..2a9bfbe12ba
--- /dev/null
+++ b/app/finders/freeze_periods_finder.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class FreezePeriodsFinder
+ def initialize(project, current_user = nil)
+ @project = project
+ @current_user = current_user
+ end
+
+ def execute
+ return Ci::FreezePeriod.none unless Ability.allowed?(@current_user, :read_freeze_period, @project)
+
+ @project.freeze_periods
+ end
+end
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index a56d4ebb368..949af103eb3 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -9,7 +9,6 @@ class GroupMembersFinder < UnionFinder
# search: string
# created_after: datetime
# created_before: datetime
-
attr_reader :params
def initialize(group, user = nil, params: {})
@@ -22,7 +21,6 @@ class GroupMembersFinder < UnionFinder
def execute(include_relations: [:inherited, :direct])
group_members = group.members
relations = []
- @params = params
return group_members if include_relations == [:direct]
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 5687b375cf0..7014f2ec205 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -40,7 +40,7 @@ class IssuableFinder
requires_cross_project_access unless: -> { params.project? }
- NEGATABLE_PARAMS_HELPER_KEYS = %i[include_subgroups in].freeze
+ NEGATABLE_PARAMS_HELPER_KEYS = %i[project_id scope status include_subgroups].freeze
attr_accessor :current_user, :params
@@ -68,7 +68,7 @@ class IssuableFinder
# This should not be used in controller strong params!
def negatable_scalar_params
- @negatable_scalar_params ||= scalar_params + %i[project_id group_id]
+ @negatable_scalar_params ||= scalar_params - %i[search in]
end
# This should not be used in controller strong params!
@@ -100,7 +100,7 @@ class IssuableFinder
items = filter_items(items)
# Let's see if we have to negate anything
- items = by_negation(items)
+ items = filter_negated_items(items)
# This has to be last as we use a CTE as an optimization fence
# for counts by passing the force_cte param and enabling the
@@ -132,6 +132,22 @@ class IssuableFinder
by_my_reaction_emoji(items)
end
+ # Negates all params found in `negatable_params`
+ def filter_negated_items(items)
+ return items unless Feature.enabled?(:not_issuable_queries, params.group || params.project, default_enabled: true)
+
+ # API endpoints send in `nil` values so we test if there are any non-nil
+ return items unless not_params.present? && not_params.values.any?
+
+ items = by_negated_author(items)
+ items = by_negated_assignee(items)
+ items = by_negated_label(items)
+ items = by_negated_milestone(items)
+ items = by_negated_release(items)
+ items = by_negated_my_reaction_emoji(items)
+ by_negated_iids(items)
+ end
+
def row_count
Gitlab::IssuablesCountForState.new(self).for_state_or_opened(params[:state])
end
@@ -189,6 +205,21 @@ class IssuableFinder
private
+ def not_params
+ strong_memoize(:not_params) do
+ params_class.new(params[:not].dup, current_user, klass).tap do |not_params|
+ next unless not_params.present?
+
+ # These are "helper" params that modify the results, like :in and :search. They usually come in at the top-level
+ # params, but if they do come in inside the `:not` params, the inner ones should take precedence.
+ not_helpers = params.slice(*NEGATABLE_PARAMS_HELPER_KEYS).merge(params[:not].slice(*NEGATABLE_PARAMS_HELPER_KEYS))
+ not_helpers.each do |key, value|
+ not_params[key] = value unless not_params[key].present?
+ end
+ end
+ end
+ end
+
def force_cte?
!!params[:force_cte]
end
@@ -215,33 +246,6 @@ class IssuableFinder
klass.available_states.key(value)
end
- # Negates all params found in `negatable_params`
- # rubocop: disable CodeReuse/ActiveRecord
- def by_negation(items)
- not_params = params[:not].dup
- # API endpoints send in `nil` values so we test if there are any non-nil
- return items unless not_params.present? && not_params.values.any?
-
- not_params.keep_if { |_k, v| v.present? }.each do |(key, value)|
- # These aren't negatable params themselves, but rather help other searches, so we skip them.
- # They will be added into all the NOT searches.
- next if NEGATABLE_PARAMS_HELPER_KEYS.include?(key.to_sym)
- next unless self.class.negatable_params.include?(key.to_sym)
-
- # These are "helper" params that are required inside the NOT to get the right results. They usually come in
- # at the top-level params, but if they do come in inside the `:not` params, they should take precedence.
- not_helpers = params.slice(*NEGATABLE_PARAMS_HELPER_KEYS).merge(params[:not].slice(*NEGATABLE_PARAMS_HELPER_KEYS))
- not_param = { key => value }.with_indifferent_access.merge(not_helpers).merge(not_query: true)
-
- items_to_negate = self.class.new(current_user, not_param).execute
-
- items = items.where.not(id: items_to_negate)
- end
-
- items
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
# rubocop: disable CodeReuse/ActiveRecord
def by_scope(items)
return items.none if params.current_user_related? && !current_user
@@ -326,6 +330,12 @@ class IssuableFinder
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
+ def by_negated_iids(items)
+ not_params[:iids].present? ? items.where.not(iid: not_params[:iids]) : items
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
def sort(items)
# Ensure we always have an explicit sort order (instead of inheriting
# multiple orders when combining ActiveRecord::Relation objects).
@@ -347,9 +357,19 @@ class IssuableFinder
end
# rubocop: enable CodeReuse/ActiveRecord
- def by_assignee(items)
- return items.assigned_to(params.assignees) if not_query? && params.assignees.any?
+ # rubocop: disable CodeReuse/ActiveRecord
+ def by_negated_author(items)
+ if not_params.author
+ items.where.not(author_id: not_params.author.id)
+ elsif not_params.author_id? || not_params.author_username? # author not found
+ items.none
+ else
+ items
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ def by_assignee(items)
if params.filter_by_no_assignee?
items.unassigned
elsif params.filter_by_any_assignee?
@@ -363,6 +383,17 @@ class IssuableFinder
end
end
+ def by_negated_assignee(items)
+ # We want CE users to be able to say "Issues not assigned to either PersonA nor PersonB"
+ if not_params.assignees.present?
+ items.not_assigned_to(not_params.assignees)
+ elsif not_params.assignee_id? || not_params.assignee_username? # assignee not found
+ items.none
+ else
+ items
+ end
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def by_milestone(items)
return items unless params.milestones?
@@ -382,6 +413,20 @@ class IssuableFinder
end
# rubocop: enable CodeReuse/ActiveRecord
+ # rubocop: disable CodeReuse/ActiveRecord
+ def by_negated_milestone(items)
+ return items unless not_params.milestones?
+
+ if not_params.filter_by_upcoming_milestone?
+ items.joins(:milestone).merge(Milestone.not_upcoming)
+ elsif not_params.filter_by_started_milestone?
+ items.joins(:milestone).merge(Milestone.not_started)
+ else
+ items.without_particular_milestone(not_params[:milestone_title])
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
def by_release(items)
return items unless params.releases?
@@ -394,6 +439,12 @@ class IssuableFinder
end
end
+ def by_negated_release(items)
+ return items unless not_params.releases?
+
+ items.without_particular_release(not_params[:release_tag], not_params[:project_id])
+ end
+
def by_label(items)
return items unless params.labels?
@@ -402,10 +453,16 @@ class IssuableFinder
elsif params.filter_by_any_label?
items.any_label
else
- items.with_label(params.label_names, params[:sort], not_query: not_query?)
+ items.with_label(params.label_names, params[:sort])
end
end
+ def by_negated_label(items)
+ return items unless not_params.labels?
+
+ items.without_particular_labels(not_params.label_names)
+ end
+
def by_my_reaction_emoji(items)
return items unless params[:my_reaction_emoji] && current_user
@@ -418,11 +475,13 @@ class IssuableFinder
end
end
- def by_non_archived(items)
- params[:non_archived].present? ? items.non_archived : items
+ def by_negated_my_reaction_emoji(items)
+ return items unless not_params[:my_reaction_emoji] && current_user
+
+ items.not_awarded(current_user, not_params[:my_reaction_emoji])
end
- def not_query?
- !!params[:not_query]
+ def by_non_archived(items)
+ params[:non_archived].present? ? items.non_archived : items
end
end
diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb
index 120ef364368..adf9f1ca9d8 100644
--- a/app/finders/issuable_finder/params.rb
+++ b/app/finders/issuable_finder/params.rb
@@ -132,6 +132,8 @@ class IssuableFinder
def project
strong_memoize(:project) do
+ next nil unless params[:project_id].present?
+
project = Project.find(params[:project_id])
project = nil unless Ability.allowed?(current_user, :"read_#{klass.to_ability_name}", project)
diff --git a/app/finders/issues_finder/params.rb b/app/finders/issues_finder/params.rb
index aaeead7c709..cd92b79265d 100644
--- a/app/finders/issues_finder/params.rb
+++ b/app/finders/issues_finder/params.rb
@@ -50,4 +50,4 @@ class IssuesFinder
end
end
-IssuableFinder::Params.prepend_if_ee('EE::IssuesFinder::Params')
+IssuesFinder::Params.prepend_if_ee('EE::IssuesFinder::Params')
diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb
index 0617f34dc8c..e08ed737ca6 100644
--- a/app/finders/members_finder.rb
+++ b/app/finders/members_finder.rb
@@ -4,17 +4,19 @@ class MembersFinder
# Params can be any of the following:
# sort: string
# search: string
+ attr_reader :params
- def initialize(project, current_user)
+ def initialize(project, current_user, params: {})
@project = project
- @current_user = current_user
@group = project.group
+ @current_user = current_user
+ @params = params
end
- def execute(include_relations: [:inherited, :direct], params: {})
- members = find_members(include_relations, params)
+ def execute(include_relations: [:inherited, :direct])
+ members = find_members(include_relations)
- filter_members(members, params)
+ filter_members(members)
end
def can?(*args)
@@ -25,7 +27,7 @@ class MembersFinder
attr_reader :project, :current_user, :group
- def find_members(include_relations, params)
+ def find_members(include_relations)
project_members = project.project_members
project_members = project_members.non_invite unless can?(current_user, :admin_project, project)
@@ -39,7 +41,7 @@ class MembersFinder
distinct_union_of_members(union_members)
end
- def filter_members(members, params)
+ def filter_members(members)
members = members.search(params[:search]) if params[:search].present?
members = members.sort_by_attribute(params[:sort]) if params[:sort].present?
members
diff --git a/app/finders/metrics/users_starred_dashboards_finder.rb b/app/finders/metrics/users_starred_dashboards_finder.rb
new file mode 100644
index 00000000000..7244c51f9a7
--- /dev/null
+++ b/app/finders/metrics/users_starred_dashboards_finder.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Metrics
+ class UsersStarredDashboardsFinder
+ def initialize(user:, project:, params: {})
+ @user, @project, @params = user, project, params
+ end
+
+ def execute
+ return ::Metrics::UsersStarredDashboard.none unless Ability.allowed?(user, :read_metrics_user_starred_dashboard, project)
+
+ items = starred_dashboards
+ items = by_project(items)
+ by_dashboard(items)
+ end
+
+ private
+
+ attr_reader :user, :project, :params
+
+ def by_project(items)
+ items.for_project(project)
+ end
+
+ def by_dashboard(items)
+ return items unless params[:dashboard_path]
+
+ items.merge(starred_dashboards.for_project_dashboard(project, params[:dashboard_path]))
+ end
+
+ def starred_dashboards
+ @starred_dashboards ||= user.metrics_users_starred_dashboards
+ end
+ end
+end
diff --git a/app/finders/projects/serverless/functions_finder.rb b/app/finders/projects/serverless/functions_finder.rb
index 3b4ecbb5387..13f84e0e3a5 100644
--- a/app/finders/projects/serverless/functions_finder.rb
+++ b/app/finders/projects/serverless/functions_finder.rb
@@ -9,6 +9,7 @@ module Projects
attr_reader :project
self.reactive_cache_key = ->(finder) { finder.cache_key }
+ self.reactive_cache_work_type = :external_dependency
self.reactive_cache_worker_finder = ->(_id, *args) { from_cache(*args) }
MAX_CLUSTERS = 10
diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb
index 3a84600b09f..8846ff54eb2 100644
--- a/app/finders/projects_finder.rb
+++ b/app/finders/projects_finder.rb
@@ -151,11 +151,11 @@ class ProjectsFinder < UnionFinder
end
def by_personal(items)
- (params[:personal].present? && current_user) ? items.personal(current_user) : items
+ params[:personal].present? && current_user ? items.personal(current_user) : items
end
def by_starred(items)
- (params[:starred].present? && current_user) ? items.starred_by(current_user) : items
+ params[:starred].present? && current_user ? items.starred_by(current_user) : items
end
def by_trending(items)
diff --git a/app/finders/releases_finder.rb b/app/finders/releases_finder.rb
index e58a90922a5..6a754fdb5a1 100644
--- a/app/finders/releases_finder.rb
+++ b/app/finders/releases_finder.rb
@@ -1,17 +1,31 @@
# frozen_string_literal: true
class ReleasesFinder
- def initialize(project, current_user = nil)
+ attr_reader :project, :current_user, :params
+
+ def initialize(project, current_user = nil, params = {})
@project = project
@current_user = current_user
+ @params = params
end
def execute(preload: true)
- return Release.none unless Ability.allowed?(@current_user, :read_release, @project)
+ return Release.none unless Ability.allowed?(current_user, :read_release, project)
# See https://gitlab.com/gitlab-org/gitlab/-/issues/211988
- releases = @project.releases.where.not(tag: nil) # rubocop:disable CodeReuse/ActiveRecord
+ releases = project.releases.where.not(tag: nil) # rubocop:disable CodeReuse/ActiveRecord
+ releases = by_tag(releases)
releases = releases.preloaded if preload
releases.sorted
end
+
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def by_tag(releases)
+ return releases unless params[:tag].present?
+
+ releases.where(tag: params[:tag])
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index e56009be33d..672bbd52b07 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -23,7 +23,7 @@ class TodosFinder
NONE = '0'
- TODO_TYPES = Set.new(%w(Issue MergeRequest)).freeze
+ TODO_TYPES = Set.new(%w(Issue MergeRequest DesignManagement::Design)).freeze
attr_accessor :current_user, :params