2018-09-11 15:08:34 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-02-20 08:59:59 -05:00
|
|
|
# TodosFinder
|
2016-02-17 22:20:31 -05:00
|
|
|
#
|
2016-02-20 08:59:59 -05:00
|
|
|
# Used to filter Todos by set of params
|
2016-02-17 22:20:31 -05:00
|
|
|
#
|
|
|
|
# Arguments:
|
|
|
|
# current_user - which user use
|
|
|
|
# params:
|
|
|
|
# action_id: integer
|
|
|
|
# author_id: integer
|
|
|
|
# project_id; integer
|
2020-08-03 11:09:44 -04:00
|
|
|
# target_id; integer
|
2016-07-11 02:10:04 -04:00
|
|
|
# state: 'pending' (default) or 'done'
|
2020-06-24 14:09:03 -04:00
|
|
|
# type: 'Issue' or 'MergeRequest' or ['Issue', 'MergeRequest']
|
2016-02-17 22:20:31 -05:00
|
|
|
#
|
|
|
|
|
2016-02-20 08:59:59 -05:00
|
|
|
class TodosFinder
|
2017-12-11 09:21:06 -05:00
|
|
|
prepend FinderWithCrossProjectAccess
|
|
|
|
include FinderMethods
|
2018-07-16 09:35:19 -04:00
|
|
|
include Gitlab::Utils::StrongMemoize
|
2017-12-11 09:21:06 -05:00
|
|
|
|
|
|
|
requires_cross_project_access unless: -> { project? }
|
|
|
|
|
2019-08-31 15:21:48 -04:00
|
|
|
NONE = '0'
|
2016-02-17 22:20:31 -05:00
|
|
|
|
2020-08-03 11:09:44 -04:00
|
|
|
TODO_TYPES = Set.new(%w(Issue MergeRequest DesignManagement::Design AlertManagement::Alert)).freeze
|
2018-09-20 09:18:04 -04:00
|
|
|
|
2016-02-17 22:20:31 -05:00
|
|
|
attr_accessor :current_user, :params
|
|
|
|
|
2019-11-11 16:06:20 -05:00
|
|
|
class << self
|
|
|
|
def todo_types
|
|
|
|
TODO_TYPES
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-06-30 11:34:19 -04:00
|
|
|
def initialize(current_user, params = {})
|
2016-02-17 22:20:31 -05:00
|
|
|
@current_user = current_user
|
|
|
|
@params = params
|
|
|
|
end
|
|
|
|
|
|
|
|
def execute
|
2019-10-17 11:06:17 -04:00
|
|
|
return Todo.none if current_user.nil?
|
2020-06-24 14:09:03 -04:00
|
|
|
raise ArgumentError, invalid_type_message unless valid_types?
|
2019-10-17 11:06:17 -04:00
|
|
|
|
2016-06-01 19:44:35 -04:00
|
|
|
items = current_user.todos
|
2016-02-17 22:20:31 -05:00
|
|
|
items = by_action_id(items)
|
2016-06-22 13:15:09 -04:00
|
|
|
items = by_action(items)
|
2016-02-17 22:20:31 -05:00
|
|
|
items = by_author(items)
|
|
|
|
items = by_state(items)
|
2020-08-03 11:09:44 -04:00
|
|
|
items = by_target_id(items)
|
2020-06-24 14:09:03 -04:00
|
|
|
items = by_types(items)
|
2018-07-16 09:35:19 -04:00
|
|
|
items = by_group(items)
|
2016-08-12 08:29:59 -04:00
|
|
|
# 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-02-17 22:20:31 -05:00
|
|
|
|
2016-07-26 17:21:20 -04:00
|
|
|
sort(items)
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
|
2019-09-18 10:02:45 -04:00
|
|
|
# Returns `true` if the current user has any todos for the given target with the optional given state.
|
2018-09-20 11:05:26 -04:00
|
|
|
#
|
|
|
|
# target - The value of the `target_type` column, such as `Issue`.
|
2019-09-18 10:02:45 -04:00
|
|
|
# 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-09-20 11:05:26 -04:00
|
|
|
end
|
|
|
|
|
2016-02-17 22:20:31 -05:00
|
|
|
private
|
|
|
|
|
|
|
|
def action_id?
|
2017-06-02 13:11:26 -04:00
|
|
|
action_id.present? && Todo::ACTION_NAMES.key?(action_id.to_i)
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def action_id
|
|
|
|
params[:action_id]
|
|
|
|
end
|
|
|
|
|
2019-10-14 14:06:24 -04:00
|
|
|
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-06-22 13:15:09 -04:00
|
|
|
def to_action_id
|
2019-10-14 14:06:24 -04:00
|
|
|
if action_array_provided?
|
|
|
|
map_actions_to_ids
|
|
|
|
else
|
|
|
|
Todo::ACTION_NAMES.key(action.to_sym)
|
|
|
|
end
|
2016-06-22 13:15:09 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def action?
|
|
|
|
action.present? && to_action_id
|
|
|
|
end
|
|
|
|
|
|
|
|
def action
|
|
|
|
params[:action]
|
|
|
|
end
|
|
|
|
|
2016-02-17 22:20:31 -05:00
|
|
|
def author?
|
|
|
|
params[:author_id].present?
|
|
|
|
end
|
|
|
|
|
|
|
|
def author
|
2018-09-20 09:18:04 -04:00
|
|
|
strong_memoize(:author) do
|
2016-02-17 22:20:31 -05:00
|
|
|
if author? && params[:author_id] != NONE
|
|
|
|
User.find(params[:author_id])
|
|
|
|
end
|
2018-09-20 09:18:04 -04:00
|
|
|
end
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def project?
|
|
|
|
params[:project_id].present?
|
|
|
|
end
|
|
|
|
|
2018-07-16 09:35:19 -04:00
|
|
|
def group?
|
|
|
|
params[:group_id].present?
|
|
|
|
end
|
|
|
|
|
|
|
|
def group
|
|
|
|
strong_memoize(:group) do
|
|
|
|
Group.find(params[:group_id])
|
2018-06-13 12:11:10 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
def types
|
|
|
|
@types ||= Array(params[:type]).reject(&:blank?)
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
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-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
|
2016-07-26 17:21:20 -04:00
|
|
|
def sort(items)
|
2018-09-20 09:18:04 -04:00
|
|
|
if params[:sort]
|
|
|
|
items.sort_by_attribute(params[:sort])
|
|
|
|
else
|
|
|
|
items.order_id_desc
|
|
|
|
end
|
2016-07-26 17:21:20 -04:00
|
|
|
end
|
|
|
|
|
2016-06-22 13:15:09 -04:00
|
|
|
def by_action(items)
|
|
|
|
if action?
|
2018-09-20 09:18:04 -04:00
|
|
|
items.for_action(to_action_id)
|
|
|
|
else
|
|
|
|
items
|
2016-06-22 13:15:09 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-10-14 14:06:24 -04:00
|
|
|
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-02-17 22:20:31 -05:00
|
|
|
def by_action_id(items)
|
2019-10-14 14:06:24 -04:00
|
|
|
return by_action_ids(items) if action_id_array_provided?
|
|
|
|
|
2016-02-17 22:20:31 -05:00
|
|
|
if action_id?
|
2019-10-14 14:06:24 -04:00
|
|
|
by_action_ids(items)
|
2018-09-20 09:18:04 -04:00
|
|
|
else
|
|
|
|
items
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def by_author(items)
|
|
|
|
if author?
|
2018-09-20 09:18:04 -04:00
|
|
|
items.for_author(author)
|
|
|
|
else
|
|
|
|
items
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def by_project(items)
|
|
|
|
if project?
|
2019-11-15 10:06:12 -05:00
|
|
|
items.for_undeleted_projects.for_project(params[:project_id])
|
2018-09-20 09:18:04 -04:00
|
|
|
else
|
|
|
|
items
|
2018-07-16 09:35:19 -04:00
|
|
|
end
|
|
|
|
end
|
2016-02-17 22:20:31 -05:00
|
|
|
|
2018-07-16 09:35:19 -04:00
|
|
|
def by_group(items)
|
2019-10-17 11:06:17 -04:00
|
|
|
return items unless group?
|
|
|
|
|
|
|
|
items.for_group_ids_and_descendants(params[:group_id])
|
2018-07-16 09:35:19 -04:00
|
|
|
end
|
|
|
|
|
2016-02-17 22:20:31 -05:00
|
|
|
def by_state(items)
|
2019-10-28 05:06:04 -04:00
|
|
|
return items.pending if params[:state].blank?
|
|
|
|
|
|
|
|
items.with_states(params[:state])
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
|
2020-08-03 11:09:44 -04:00
|
|
|
def by_target_id(items)
|
|
|
|
return items if params[:target_id].blank?
|
|
|
|
|
|
|
|
items.for_target(params[:target_id])
|
|
|
|
end
|
|
|
|
|
2020-06-24 14:09:03 -04:00
|
|
|
def by_types(items)
|
|
|
|
if types.any?
|
|
|
|
items.for_type(types)
|
2018-09-20 09:18:04 -04:00
|
|
|
else
|
|
|
|
items
|
2016-02-17 22:20:31 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-11-11 16:06:20 -05:00
|
|
|
|
2021-05-11 17:10:21 -04:00
|
|
|
TodosFinder.prepend_mod_with('TodosFinder')
|