todos_helper.rb 5.25 KB
Newer Older
1 2
# frozen_string_literal: true

3 4
module TodosHelper
  def todos_pending_count
5
    @todos_pending_count ||= current_user.todos_pending_count
6 7
  end

8
  def todos_count_format(count)
9
    count > 99 ? '99+' : count.to_s
10 11
  end

12
  def todos_done_count
13
    @todos_done_count ||= current_user.todos_done_count
14 15
  end

16 17
  def todo_action_name(todo)
    case todo.action
18 19
    when Todo::ASSIGNED then todo.self_added? ? 'assigned' : 'assigned you'
    when Todo::MENTIONED then "mentioned #{todo_action_subject(todo)} on"
20
    when Todo::BUILD_FAILED then 'The build failed for'
Phil Hughes's avatar
Phil Hughes committed
21
    when Todo::MARKED then 'added a todo for'
22
    when Todo::APPROVAL_REQUIRED then "set #{todo_action_subject(todo)} as an approver for"
23
    when Todo::UNMERGEABLE then 'Could not merge'
24
    when Todo::DIRECTLY_ADDRESSED then "directly addressed #{todo_action_subject(todo)} on"
25 26 27
    end
  end

28
  def todo_target_link(todo)
29
    text = raw(todo_target_type_name(todo) + ' ') +
30 31 32 33 34
      if todo.for_commit?
        content_tag(:span, todo.target_reference, class: 'commit-sha')
      else
        todo.target_reference
      end
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
    link_to text, todo_target_path(todo)
  end

  def todo_target_title(todo)
    if todo.target
      "\"#{todo.target.title}\""
    else
      ""
    end
  end

  def todo_parent_path(todo)
    if todo.parent.is_a?(Group)
      link_to todo.parent.name, group_path(todo.parent)
    else
      link_to_project(todo.project)
    end
53 54
  end

55 56 57 58
  def todo_target_type_name(todo)
    todo.target_type.titleize.downcase
  end

59
  def todo_target_path(todo)
60 61
    return unless todo.target.present?

62
    path_options = todo_target_path_options(todo)
63

64
    if todo.for_commit?
65
      project_commit_path(todo.project, todo.target, path_options)
66
    else
67
      path = [todo.parent, todo.target]
68 69

      path.unshift(:pipelines) if todo.build_failed?
70

71
      polymorphic_path(path, path_options)
72
    end
73 74
  end

75 76 77 78 79 80 81 82
  def todo_target_path_options(todo)
    { anchor: todo_target_path_anchor(todo) }
  end

  def todo_target_path_anchor(todo)
    dom_id(todo.note) if todo.note.present?
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
83
  def todo_target_state_pill(todo)
84 85
    return unless show_todo_state?(todo)

86 87 88 89 90 91 92 93
    type =
      case todo.target
      when MergeRequest
        'mr'
      when Issue
        'issue'
      end

94
    content_tag(:span, nil, class: 'target-status') do
95
      content_tag(:span, nil, class: "status-box status-box-#{type}-#{todo.target.state.dasherize}") do
96
        todo.target.state.capitalize
Alfredo Sumaran's avatar
Alfredo Sumaran committed
97
      end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
98
    end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
99 100
  end

Douwe Maan's avatar
Douwe Maan committed
101 102 103 104 105 106
  def todos_filter_params
    {
      state:      params[:state],
      project_id: params[:project_id],
      author_id:  params[:author_id],
      type:       params[:type],
107
      action_id:  params[:action_id]
Douwe Maan's avatar
Douwe Maan committed
108 109 110
    }
  end

111
  def todos_filter_empty?
112
    todos_filter_params.values.none?
113 114
  end

Douwe Maan's avatar
Douwe Maan committed
115 116 117 118 119 120 121 122 123 124 125
  def todos_filter_path(options = {})
    without = options.delete(:without)

    options = todos_filter_params.merge(options)

    if without.present?
      without.each do |key|
        options.delete(key)
      end
    end

126
    "#{request.path}?#{options.to_param}"
Douwe Maan's avatar
Douwe Maan committed
127 128
  end

129
  def todo_actions_options
130 131 132
    [
      { id: '', text: 'Any Action' },
      { id: Todo::ASSIGNED, text: 'Assigned' },
Jacopo's avatar
Jacopo committed
133 134
      { id: Todo::MENTIONED, text: 'Mentioned' },
      { id: Todo::MARKED, text: 'Added' },
135 136
      { id: Todo::BUILD_FAILED, text: 'Pipelines' },
      { id: Todo::DIRECTLY_ADDRESSED, text: 'Directly addressed' }
137 138 139 140
    ]
  end

  def todo_projects_options
141
    projects = current_user.authorized_projects.sorted_by_activity.non_archived.with_route
142 143

    projects = projects.map do |project|
144
      { id: project.id, text: project.full_name }
145 146
    end

147
    projects.unshift({ id: '', text: 'Any Project' }).to_json
148 149 150
  end

  def todo_types_options
151
    [
152 153 154
      { id: '', text: 'Any Type' },
      { id: 'Issue', text: 'Issue' },
      { id: 'MergeRequest', text: 'Merge Request' }
155 156
    ]
  end
Alfredo Sumaran's avatar
Alfredo Sumaran committed
157

158 159 160 161 162 163 164 165 166 167
  def todo_actions_dropdown_label(selected_action_id, default_action)
    selected_action = todo_actions_options.find { |action| action[:id] == selected_action_id.to_i}
    selected_action ? selected_action[:text] : default_action
  end

  def todo_types_dropdown_label(selected_type, default_type)
    selected_type = todo_types_options.find { |type| type[:id] == selected_type && type[:id] != '' }
    selected_type ? selected_type[:text] : default_type
  end

168
  def todo_due_date(todo)
169 170
    return unless todo.target.try(:due_date)

171 172 173 174 175 176 177 178 179 180
    is_due_today = todo.target.due_date.today?
    is_overdue = todo.target.overdue?
    css_class =
      if is_due_today
        'text-warning'
      elsif is_overdue
        'text-danger'
      else
        ''
      end
181

182
    content = content_tag(:span, class: css_class) do
183 184
      "Due #{is_due_today ? "today" : todo.target.due_date.to_s(:medium)}"
    end
185 186

    "· #{content}".html_safe
187 188
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
189 190
  private

191 192 193 194
  def todo_action_subject(todo)
    todo.self_added? ? 'yourself' : 'you'
  end

Alfredo Sumaran's avatar
Alfredo Sumaran committed
195
  def show_todo_state?(todo)
Douwe Maan's avatar
Douwe Maan committed
196
    (todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && %w(closed merged).include?(todo.target.state)
Alfredo Sumaran's avatar
Alfredo Sumaran committed
197
  end
198 199

  def todo_group_options
200
    groups = current_user.authorized_groups.with_route.map do |group|
201 202 203 204 205
      { id: group.id, text: group.full_name }
    end

    groups.unshift({ id: '', text: 'Any Group' }).to_json
  end
206
end
207

208
TodosHelper.prepend_if_ee('EE::NotesHelper'); TodosHelper.prepend_if_ee('EE::TodosHelper') # rubocop: disable Style/Semicolon