summaryrefslogtreecommitdiff
path: root/app/finders/pending_todos_finder.rb
blob: babff65cc37ede974f1ab3399bcba75d35b7e4bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# frozen_string_literal: true

# Finder for retrieving the pending todos of a user, optionally filtered using
# various fields.
#
# While this finder is a bit more verbose compared to use
# `where(params.slice(...))`, it allows us to decouple the input parameters from
# the actual column names. For example, if we ever decide to use separate
# columns for target types (e.g. `issue_id`, `merge_request_id`, etc), we no
# longer need to change _everything_ that uses this finder. Instead, we just
# change the various `by_*` methods in this finder, without having to touch
# everything that uses it.
class PendingTodosFinder
  attr_reader :users, :params

  # users - The list of users to retrieve the todos for.
  # params - A Hash containing columns and values to use for filtering todos.
  def initialize(users, params = {})
    @users = users
    @params = params
  end

  def execute
    todos = Todo.for_user(users)
    todos = todos.pending
    todos = by_project(todos)
    todos = by_target_id(todos)
    todos = by_target_type(todos)
    todos = by_discussion(todos)
    todos = by_commit_id(todos)
    by_action(todos)
  end

  def by_project(todos)
    if (id = params[:project_id])
      todos.for_project(id)
    else
      todos
    end
  end

  def by_target_id(todos)
    if (id = params[:target_id])
      todos.for_target(id)
    else
      todos
    end
  end

  def by_target_type(todos)
    if (type = params[:target_type])
      todos.for_type(type)
    else
      todos
    end
  end

  def by_commit_id(todos)
    if (id = params[:commit_id])
      todos.for_commit(id)
    else
      todos
    end
  end

  def by_discussion(todos)
    if (discussion = params[:discussion])
      todos.for_note(discussion.notes)
    else
      todos
    end
  end

  def by_action(todos)
    return todos if params[:action].blank?

    todos.for_action(params[:action])
  end
end