debian-mirror-gitlab/app/finders/todos_finder.rb

219 lines
4.3 KiB
Ruby
Raw Normal View History

2018-12-05 23:21:45 +05:30
# frozen_string_literal: true
2016-04-02 18:10:28 +05:30
# TodosFinder
#
# Used to filter Todos by set of params
#
# Arguments:
# current_user - which user use
# params:
# action_id: integer
# author_id: integer
# project_id; integer
2020-10-24 23:57:45 +05:30
# target_id; integer
2016-08-24 12:49:21 +05:30
# state: 'pending' (default) or 'done'
2020-07-28 23:09:34 +05:30
# type: 'Issue' or 'MergeRequest' or ['Issue', 'MergeRequest']
2016-04-02 18:10:28 +05:30
#
class TodosFinder
2018-03-27 19:54:05 +05:30
prepend FinderWithCrossProjectAccess
include FinderMethods
2018-11-18 11:00:15 +05:30
include Gitlab::Utils::StrongMemoize
2018-03-27 19:54:05 +05:30
requires_cross_project_access unless: -> { project? }
2019-12-04 20:38:33 +05:30
NONE = '0'
2016-04-02 18:10:28 +05:30
2020-10-24 23:57:45 +05:30
TODO_TYPES = Set.new(%w(Issue MergeRequest DesignManagement::Design AlertManagement::Alert)).freeze
2018-12-13 13:39:08 +05:30
2016-04-02 18:10:28 +05:30
attr_accessor :current_user, :params
2019-12-26 22:10:19 +05:30
class << self
def todo_types
TODO_TYPES
end
end
2016-09-13 17:45:13 +05:30
def initialize(current_user, params = {})
2016-04-02 18:10:28 +05:30
@current_user = current_user
@params = params
end
def execute
2019-12-21 20:55:43 +05:30
return Todo.none if current_user.nil?
2020-07-28 23:09:34 +05:30
raise ArgumentError, invalid_type_message unless valid_types?
2019-12-21 20:55:43 +05:30
2016-04-02 18:10:28 +05:30
items = current_user.todos
items = by_action_id(items)
2016-08-24 12:49:21 +05:30
items = by_action(items)
2016-04-02 18:10:28 +05:30
items = by_author(items)
items = by_state(items)
2020-10-24 23:57:45 +05:30
items = by_target_id(items)
2020-07-28 23:09:34 +05:30
items = by_types(items)
2018-11-18 11:00:15 +05:30
items = by_group(items)
2016-09-13 17:45:13 +05:30
# Filtering by project HAS TO be the last because we use
# the project IDs yielded by the todos query thus far
items = by_project(items)
2016-04-02 18:10:28 +05:30
2016-09-13 17:45:13 +05:30
sort(items)
2016-04-02 18:10:28 +05:30
end
2019-12-04 20:38:33 +05:30
# Returns `true` if the current user has any todos for the given target with the optional given state.
2018-12-13 13:39:08 +05:30
#
# target - The value of the `target_type` column, such as `Issue`.
2019-12-04 20:38:33 +05:30
# state - The value of the `state` column, such as `pending` or `done`.
def any_for_target?(target, state = nil)
current_user.todos.any_for_target?(target, state)
2018-12-13 13:39:08 +05:30
end
2016-04-02 18:10:28 +05:30
private
def action_id?
2017-09-10 17:25:29 +05:30
action_id.present? && Todo::ACTION_NAMES.key?(action_id.to_i)
2016-04-02 18:10:28 +05:30
end
def action_id
params[:action_id]
end
2019-12-21 20:55:43 +05:30
def action_array_provided?
params[:action].is_a?(Array)
end
def map_actions_to_ids
params[:action].map { |item| Todo::ACTION_NAMES.key(item.to_sym) }
end
2016-08-24 12:49:21 +05:30
def to_action_id
2019-12-21 20:55:43 +05:30
if action_array_provided?
map_actions_to_ids
else
Todo::ACTION_NAMES.key(action.to_sym)
end
2016-08-24 12:49:21 +05:30
end
def action?
action.present? && to_action_id
end
def action
params[:action]
end
2016-04-02 18:10:28 +05:30
def author?
params[:author_id].present?
end
def author
2018-12-13 13:39:08 +05:30
strong_memoize(:author) do
2016-04-02 18:10:28 +05:30
if author? && params[:author_id] != NONE
User.find(params[:author_id])
end
2018-12-13 13:39:08 +05:30
end
2016-04-02 18:10:28 +05:30
end
def project?
params[:project_id].present?
end
2018-11-18 11:00:15 +05:30
def group?
params[:group_id].present?
end
def group
strong_memoize(:group) do
Group.find(params[:group_id])
2017-09-10 17:25:29 +05:30
end
end
2020-07-28 23:09:34 +05:30
def types
@types ||= Array(params[:type]).reject(&:blank?)
2016-04-02 18:10:28 +05:30
end
2020-07-28 23:09:34 +05:30
def valid_types?
types.all? { |type| self.class.todo_types.include?(type) }
end
def invalid_type_message
_("Unsupported todo type passed. Supported todo types are: %{todo_types}") % { todo_types: self.class.todo_types.to_a.join(', ') }
2016-04-02 18:10:28 +05:30
end
2016-09-13 17:45:13 +05:30
def sort(items)
2018-12-13 13:39:08 +05:30
if params[:sort]
items.sort_by_attribute(params[:sort])
else
items.order_id_desc
end
2016-09-13 17:45:13 +05:30
end
2016-08-24 12:49:21 +05:30
def by_action(items)
if action?
2018-12-13 13:39:08 +05:30
items.for_action(to_action_id)
else
items
2016-08-24 12:49:21 +05:30
end
end
2019-12-21 20:55:43 +05:30
def action_id_array_provided?
params[:action_id].is_a?(Array) && params[:action_id].any?
end
def by_action_ids(items)
items.for_action(action_id)
end
2016-04-02 18:10:28 +05:30
def by_action_id(items)
2019-12-21 20:55:43 +05:30
return by_action_ids(items) if action_id_array_provided?
2016-04-02 18:10:28 +05:30
if action_id?
2019-12-21 20:55:43 +05:30
by_action_ids(items)
2018-12-13 13:39:08 +05:30
else
items
2016-04-02 18:10:28 +05:30
end
end
def by_author(items)
if author?
2018-12-13 13:39:08 +05:30
items.for_author(author)
else
items
2016-04-02 18:10:28 +05:30
end
end
def by_project(items)
if project?
2019-12-26 22:10:19 +05:30
items.for_undeleted_projects.for_project(params[:project_id])
2018-12-13 13:39:08 +05:30
else
items
2018-11-18 11:00:15 +05:30
end
end
def by_group(items)
2019-12-21 20:55:43 +05:30
return items unless group?
items.for_group_ids_and_descendants(params[:group_id])
2016-04-02 18:10:28 +05:30
end
def by_state(items)
2019-12-26 22:10:19 +05:30
return items.pending if params[:state].blank?
items.with_states(params[:state])
2016-04-02 18:10:28 +05:30
end
2020-10-24 23:57:45 +05:30
def by_target_id(items)
return items if params[:target_id].blank?
items.for_target(params[:target_id])
end
2020-07-28 23:09:34 +05:30
def by_types(items)
if types.any?
items.for_type(types)
2018-12-13 13:39:08 +05:30
else
items
2016-04-02 18:10:28 +05:30
end
end
end
2019-12-26 22:10:19 +05:30
2021-06-08 01:23:25 +05:30
TodosFinder.prepend_mod_with('TodosFinder')