summaryrefslogtreecommitdiff
path: root/app/helpers/labels_helper.rb
blob: e0a8552dfa757c37c10d1c150b57855d5986f3fc (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
module LabelsHelper
  include ActionView::Helpers::TagHelper

  # Link to a Label
  #
  # label   - Label object to link to
  # project - Project object which will be used as the context for the label's
  #           link. If omitted, defaults to `@project`, or the label's own
  #           project.
  # type    - The type of item the link will point to (:issue or
  #           :merge_request). If omitted, defaults to :issue.
  # block   - An optional block that will be passed to `link_to`, forming the
  #           body of the link element. If omitted, defaults to
  #           `render_colored_label`.
  #
  # Examples:
  #
  #   # Allow the generated link to use the label's own project
  #   link_to_label(label)
  #
  #   # Force the generated link to use @project
  #   @project = Project.first
  #   link_to_label(label)
  #
  #   # Force the generated link to use a provided project
  #   link_to_label(label, project: Project.last)
  #
  #   # Force the generated link to point to merge requests instead of issues
  #   link_to_label(label, type: :merge_request)
  #
  #   # Customize link body with a block
  #   link_to_label(label) { "My Custom Label Text" }
  #
  # Returns a String
  def link_to_label(label, project: nil, type: :issue, tooltip: true, &block)
    project ||= @project || label.project
    link = send("namespace_project_#{type.to_s.pluralize}_path",
                project.namespace,
                project,
                label_name: label.name)

    if block_given?
      link_to link, &block
    else
      link_to render_colored_label(label, tooltip: tooltip), link
    end
  end

  def project_label_names
    @project.labels.pluck(:title)
  end

  def render_colored_label(label, label_suffix = '', tooltip: true)
    label_color = label.color || Label::DEFAULT_COLOR
    text_color = text_color_for_bg(label_color)

    # Intentionally not using content_tag here so that this method can be called
    # by LabelReferenceFilter
    span = %(<span class="label color-label #{"has-tooltip" if tooltip}" ) +
      %(style="background-color: #{label_color}; color: #{text_color}" ) +
      %(title="#{escape_once(label.description)}" data-container="body">) +
      %(#{escape_once(label.name)}#{label_suffix}</span>)

    span.html_safe
  end

  def render_colored_cross_project_label(label, tooltip: true)
    label_suffix = label.project.name_with_namespace
    label_suffix = " <i>in #{escape_once(label_suffix)}</i>"
    render_colored_label(label, label_suffix, tooltip: tooltip)
  end

  def suggested_colors
    [
      '#0033CC',
      '#428BCA',
      '#44AD8E',
      '#A8D695',
      '#5CB85C',
      '#69D100',
      '#004E00',
      '#34495E',
      '#7F8C8D',
      '#A295D6',
      '#5843AD',
      '#8E44AD',
      '#FFECDB',
      '#AD4363',
      '#D10069',
      '#CC0033',
      '#FF0000',
      '#D9534F',
      '#D1D100',
      '#F0AD4E',
      '#AD8D43'
    ]
  end

  def text_color_for_bg(bg_color)
    if bg_color.length == 4
      r, g, b = bg_color[1, 4].scan(/./).map { |v| (v * 2).hex }
    else
      r, g, b = bg_color[1, 7].scan(/.{2}/).map(&:hex)
    end

    if (r + g + b) > 500
      '#333333'
    else
      '#FFFFFF'
    end
  end

  def labels_filter_path
    if @project
      namespace_project_labels_path(@project.namespace, @project, :json)
    else
      labels_dashboard_path(:json)
    end
  end

  def label_subscription_status(label)
    label.subscribed?(current_user) ? 'subscribed' : 'unsubscribed'
  end

  def label_subscription_toggle_button_text(label)
    label.subscribed?(current_user) ? 'Unsubscribe' : 'Subscribe'
  end

  # Required for Banzai::Filter::LabelReferenceFilter
  module_function :render_colored_label, :render_colored_cross_project_label,
                  :text_color_for_bg, :escape_once
end