issuables_helper.rb 6.58 KB
Newer Older
1
2
3
4
5
6
7
8
9
module IssuablesHelper
  def sidebar_gutter_toggle_icon
    sidebar_gutter_collapsed? ? icon('angle-double-left') : icon('angle-double-right')
  end

  def sidebar_gutter_collapsed_class
    "right-sidebar-#{sidebar_gutter_collapsed? ? 'collapsed' : 'expanded'}"
  end

10
  def multi_label_name(current_labels, default_label)
11
    if current_labels && current_labels.any?
12
      title = current_labels.first.try(:title)
13
14
      if current_labels.size > 1
        "#{title} +#{current_labels.size - 1} more"
15
      else
16
        title
17
      end
Arinde Eniola's avatar
Arinde Eniola committed
18
    else
19
      default_label
20
21
22
    end
  end

Jacob Schatz's avatar
Jacob Schatz committed
23
24
25
26
27
28
29
30
31
32
  def issuable_json_path(issuable)
    project = issuable.project

    if issuable.kind_of?(MergeRequest)
      namespace_project_merge_request_path(project.namespace, project, issuable.iid, :json)
    else
      namespace_project_issue_path(project.namespace, project, issuable.iid, :json)
    end
  end

33
34
35
36
37
38
39
40
41
  def serialize_issuable(issuable)
    case issuable
    when Issue
      IssueSerializer.new.represent(issuable).to_json
    when MergeRequest
      MergeRequestSerializer.new.represent(issuable).to_json
    end
  end

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  def template_dropdown_tag(issuable, &block)
    title = selected_template(issuable) || "Choose a template"
    options = {
      toggle_class: 'js-issuable-selector',
      title: title,
      filter: true,
      placeholder: 'Filter',
      footer_content: true,
      data: {
        data: issuable_templates(issuable),
        field_name: 'issuable_template',
        selected: selected_template(issuable),
        project_path: ref_project.path,
        namespace_path: ref_project.namespace.path
      }
    }

    dropdown_tag(title, options: options) do
      capture(&block)
    end
  end

64
  def user_dropdown_label(user_id, default_label)
Phil Hughes's avatar
Phil Hughes committed
65
    return default_label if user_id.nil?
66
67
    return "Unassigned" if user_id == "0"

Phil Hughes's avatar
Phil Hughes committed
68
    user = User.find_by(id: user_id)
69
70
71
72
73
74
75
76

    if user
      user.name
    else
      default_label
    end
  end

77
78
79
80
81
82
83
  def project_dropdown_label(project_id, default_label)
    return default_label if project_id.nil?
    return "Any project" if project_id == "0"

    project = Project.find_by(id: project_id)

    if project
84
      project.name_with_namespace
85
86
87
88
89
    else
      default_label
    end
  end

Phil Hughes's avatar
Phil Hughes committed
90
  def milestone_dropdown_label(milestone_title, default_label = "Milestone")
Phil Hughes's avatar
Phil Hughes committed
91
92
    if milestone_title == Milestone::Upcoming.name
      milestone_title = Milestone::Upcoming.title
93
    end
Phil Hughes's avatar
Phil Hughes committed
94
95

    h(milestone_title.presence || default_label)
96
97
  end

98
99
  def issuable_meta(issuable, project, text)
    output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier"
100
    output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
101
    output << content_tag(:strong) do
102
      author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs", tooltip: true)
103
104
      author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg")
    end
105
106
107

    if issuable.tasks?
      output << "&ensp;".html_safe
108
109
      output << content_tag(:span, issuable.task_status, id: "task_status", class: "hidden-xs hidden-sm")
      output << content_tag(:span, issuable.task_status_short, id: "task_status_short", class: "hidden-md hidden-lg")
110
111
112
    end

    output
113
114
  end

Phil Hughes's avatar
Phil Hughes committed
115
  def issuable_todo(issuable)
116
    if current_user
Phil Hughes's avatar
Phil Hughes committed
117
      current_user.todos.find_by(target: issuable, state: :pending)
118
    end
119
120
  end

Phil Hughes's avatar
Phil Hughes committed
121
  def issuable_labels_tooltip(labels, limit: 5)
Phil Hughes's avatar
Phil Hughes committed
122
    first, last = labels.partition.with_index{ |_, i| i < limit  }
123

Phil Hughes's avatar
Phil Hughes committed
124
125
    label_names = first.collect(&:name)
    label_names << "and #{last.size} more" unless last.empty?
126

Phil Hughes's avatar
Phil Hughes committed
127
    label_names.join(', ')
128
129
  end

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
  def issuables_state_counter_text(issuable_type, state)
    titles = {
      opened: "Open"
    }

    state_title = titles[state] || state.to_s.humanize

    count =
      Rails.cache.fetch(issuables_state_counter_cache_key(issuable_type, state), expires_in: 2.minutes) do
        issuables_count_for_state(issuable_type, state)
      end

    html = content_tag(:span, state_title)
    html << " " << content_tag(:span, number_with_delimiter(count), class: 'badge')

    html.html_safe
  end

148
  def cached_assigned_issuables_count(assignee, issuable_type, state)
149
    cache_key = hexdigest(['assigned_issuables_count', assignee.id, issuable_type, state].join('-'))
150
151
152
153
154
    Rails.cache.fetch(cache_key, expires_in: 2.minutes) do
      assigned_issuables_count(assignee, issuable_type, state)
    end
  end

155
156
157
158
159
160
161
162
163
164
  def issuable_filter_params
    [
      :search,
      :author_id,
      :assignee_id,
      :milestone_title,
      :label_name
    ]
  end

165
166
167
168
  def issuable_reference(issuable)
    @show_full_reference ? issuable.to_reference(full: true) : issuable.to_reference(@group || @project)
  end

169
170
171
172
  def issuable_filter_present?
    issuable_filter_params.any? { |k| params.key?(k) }
  end

173
174
  private

175
  def assigned_issuables_count(assignee, issuable_type, state)
176
    assignee.public_send("assigned_#{issuable_type}").public_send(state).count
177
178
  end

179
180
181
182
183
  def sidebar_gutter_collapsed?
    cookies[:collapsed_gutter] == 'true'
  end

  def base_issuable_scope(issuable)
184
    issuable.project.send(issuable.class.table_name).send(issuable_state_scope(issuable))
185
186
187
  end

  def issuable_state_scope(issuable)
188
189
190
191
192
    if issuable.respond_to?(:merged?) && issuable.merged?
      :merged
    else
      issuable.open? ? :opened : :closed
    end
193
  end
194
195

  def issuables_count_for_state(issuable_type, state)
196
197
198
    @counts ||= {}
    @counts[issuable_type] ||= public_send("#{issuable_type}_finder").count_by_state
    @counts[issuable_type][state]
199
200
  end

Douwe Maan's avatar
Douwe Maan committed
201
  IRRELEVANT_PARAMS_FOR_CACHE_KEY = %i[utf8 sort page].freeze
202
203
204
  private_constant :IRRELEVANT_PARAMS_FOR_CACHE_KEY

  def issuables_state_counter_cache_key(issuable_type, state)
205
206
207
    opts = params.with_indifferent_access
    opts[:state] = state
    opts.except!(*IRRELEVANT_PARAMS_FOR_CACHE_KEY)
208
    opts.delete_if { |_, value| value.blank? }
209
210
211

    hexdigest(['issuables_count', issuable_type, opts.sort].flatten.join('-'))
  end
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235

  def issuable_templates(issuable)
    @issuable_templates ||=
      case issuable
      when Issue
        issue_template_names
      when MergeRequest
        merge_request_template_names
      else
        raise 'Unknown issuable type!'
      end
  end

  def merge_request_template_names
    @merge_request_templates ||= Gitlab::Template::MergeRequestTemplate.dropdown_names(ref_project)
  end

  def issue_template_names
    @issue_templates ||= Gitlab::Template::IssueTemplate.dropdown_names(ref_project)
  end

  def selected_template(issuable)
    params[:issuable_template] if issuable_templates(issuable).include?(params[:issuable_template])
  end
236
end