Read about our upcoming Code of Conduct on this issue

labels_helper.rb 4.85 KB
Newer Older
1
module LabelsHelper
2
3
  include ActionView::Helpers::TagHelper

Robert Speicher's avatar
Robert Speicher committed
4
5
6
  # Link to a Label
  #
  # label   - Label object to link to
7
8
  # subject - Project/Group object which will be used as the context for the
  #           label's link. If omitted, defaults to the label's own group/project.
9
10
  # type    - The type of item the link will point to (:issue or
  #           :merge_request). If omitted, defaults to :issue.
Robert Speicher's avatar
Robert Speicher committed
11
12
13
14
15
16
  # 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:
  #
17
  #   # Allow the generated link to use the label's own subject
Robert Speicher's avatar
Robert Speicher committed
18
19
  #   link_to_label(label)
  #
20
21
  #   # Force the generated link to use a provided group
  #   link_to_label(label, subject: Group.last)
Robert Speicher's avatar
Robert Speicher committed
22
23
  #
  #   # Force the generated link to use a provided project
24
  #   link_to_label(label, subject: Project.last)
Robert Speicher's avatar
Robert Speicher committed
25
  #
26
27
28
  #   # Force the generated link to point to merge requests instead of issues
  #   link_to_label(label, type: :merge_request)
  #
Robert Speicher's avatar
Robert Speicher committed
29
30
31
32
  #   # Customize link body with a block
  #   link_to_label(label) { "My Custom Label Text" }
  #
  # Returns a String
33
  def link_to_label(label, subject: nil, type: :issue, tooltip: true, css_class: nil, &block)
34
    link = label_filter_path(subject || label.subject, label, type: type)
Robert Speicher's avatar
Robert Speicher committed
35
36

    if block_given?
Phil Hughes's avatar
Phil Hughes committed
37
      link_to link, class: css_class, &block
Robert Speicher's avatar
Robert Speicher committed
38
    else
Phil Hughes's avatar
Phil Hughes committed
39
      link_to render_colored_label(label, tooltip: tooltip), link, class: css_class
Robert Speicher's avatar
Robert Speicher committed
40
41
42
    end
  end

43
  def label_filter_path(subject, label, type: :issue)
44
45
    case subject
    when Group
46
      send("#{type.to_s.pluralize}_group_path",
47
                  subject,
48
                  label_name: [label.name])
49
    when Project
50
      send("namespace_project_#{type.to_s.pluralize}_path",
51
52
                  subject.namespace,
                  subject,
53
54
                  label_name: [label.name])
    end
55
56
  end

57
58
59
  def edit_label_path(label)
    case label
    when GroupLabel then edit_group_label_path(label.group, label)
60
    when ProjectLabel then edit_namespace_project_label_path(label.project.namespace, label.project, label)
61
62
63
64
65
66
    end
  end

  def destroy_label_path(label)
    case label
    when GroupLabel then group_label_path(label.group, label)
67
    when ProjectLabel then namespace_project_label_path(label.project.namespace, label.project, label)
68
69
70
    end
  end

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

Robert Speicher's avatar
Robert Speicher committed
75
76
    # Intentionally not using content_tag here so that this method can be called
    # by LabelReferenceFilter
77
    span = %(<span class="label color-label #{"has-tooltip" if tooltip}" ) +
78
79
      %(style="background-color: #{label_color}; color: #{text_color}" ) +
      %(title="#{escape_once(label.description)}" data-container="body">) +
80
      %(#{escape_once(label.name)}#{label_suffix}</span>)
Robert Speicher's avatar
Robert Speicher committed
81
82

    span.html_safe
83
  end
84
85
86

  def suggested_colors
    [
phortx's avatar
phortx committed
87
      '#0033CC',
88
      '#428BCA',
phortx's avatar
phortx committed
89
90
      '#44AD8E',
      '#A8D695',
91
      '#5CB85C',
phortx's avatar
phortx committed
92
93
      '#69D100',
      '#004E00',
94
95
      '#34495E',
      '#7F8C8D',
phortx's avatar
phortx committed
96
97
      '#A295D6',
      '#5843AD',
98
      '#8E44AD',
phortx's avatar
phortx committed
99
      '#FFECDB',
100
101
102
103
104
105
106
107
      '#AD4363',
      '#D10069',
      '#CC0033',
      '#FF0000',
      '#D9534F',
      '#D1D100',
      '#F0AD4E',
      '#AD8D43'
108
109
    ]
  end
110
111

  def text_color_for_bg(bg_color)
112
113
114
115
116
    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
117
118

    if (r + g + b) > 500
Robert Speicher's avatar
Robert Speicher committed
119
      '#333333'
120
    else
Robert Speicher's avatar
Robert Speicher committed
121
      '#FFFFFF'
122
123
    end
  end
124

Phil Hughes's avatar
Phil Hughes committed
125
  def labels_filter_path
126
127
    return group_labels_path(@group, :json) if @group

128
    project = @target_project || @project
129

130
    if project
131
      namespace_project_labels_path(project.namespace, project, :json)
Phil Hughes's avatar
Phil Hughes committed
132
    else
133
      dashboard_labels_path(:json)
Phil Hughes's avatar
Phil Hughes committed
134
    end
135
  end
Robert Speicher's avatar
Robert Speicher committed
136

137
  def label_subscription_status(label, project)
138
139
140
141
142
143
144
    return 'project-level' if label.subscribed?(current_user, project)
    return 'group-level' if label.subscribed?(current_user)

    'unsubscribed'
  end

  def group_label_unsubscribe_path(label, project)
145
    case label_subscription_status(label, project)
146
147
148
149
150
    when 'project-level' then toggle_subscription_namespace_project_label_path(@project.namespace, @project, label)
    when 'group-level' then toggle_subscription_group_label_path(label.group, label)
    end
  end

151
  def label_subscription_toggle_button_text(label, project)
152
    label.subscribed?(current_user, project) ? 'Unsubscribe' : 'Subscribe'
153
154
  end

155
156
157
158
159
160
161
  def label_deletion_confirm_text(label)
    case label
    when GroupLabel then 'Remove this label? This will affect all projects within the group. Are you sure?'
    when ProjectLabel then 'Remove this label? Are you sure?'
    end
  end

162
  # Required for Banzai::Filter::LabelReferenceFilter
163
  module_function :render_colored_label, :text_color_for_bg, :escape_once
164
end