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

4 5 6 7 8 9 10
  def show_label_issuables_link?(label, issuables_type, current_user: nil, project: nil)
    return true if label.is_a?(GroupLabel)
    return true unless project

    project.feature_available?(issuables_type, current_user)
  end

Robert Speicher's avatar
Robert Speicher committed
11 12 13
  # Link to a Label
  #
  # label   - Label object to link to
14 15
  # 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.
16 17
  # 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
18 19 20 21 22 23
  # 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:
  #
24
  #   # Allow the generated link to use the label's own subject
Robert Speicher's avatar
Robert Speicher committed
25 26
  #   link_to_label(label)
  #
27 28
  #   # Force the generated link to use a provided group
  #   link_to_label(label, subject: Group.last)
Robert Speicher's avatar
Robert Speicher committed
29 30
  #
  #   # Force the generated link to use a provided project
31
  #   link_to_label(label, subject: Project.last)
Robert Speicher's avatar
Robert Speicher committed
32
  #
33 34 35
  #   # 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
36 37 38 39
  #   # Customize link body with a block
  #   link_to_label(label) { "My Custom Label Text" }
  #
  # Returns a String
40
  def link_to_label(label, subject: nil, type: :issue, tooltip: true, css_class: nil, &block)
41
    link = label_filter_path(subject || label.subject, label, type: type)
Robert Speicher's avatar
Robert Speicher committed
42 43

    if block_given?
Phil Hughes's avatar
Phil Hughes committed
44
      link_to link, class: css_class, &block
Robert Speicher's avatar
Robert Speicher committed
45
    else
Phil Hughes's avatar
Phil Hughes committed
46
      link_to render_colored_label(label, tooltip: tooltip), link, class: css_class
Robert Speicher's avatar
Robert Speicher committed
47 48 49
    end
  end

50
  def label_filter_path(subject, label, type: :issue)
51 52
    case subject
    when Group
53
      send("#{type.to_s.pluralize}_group_path", # rubocop:disable GitlabSecurity/PublicSend
54
                  subject,
55
                  label_name: [label.name])
56
    when Project
57
      send("namespace_project_#{type.to_s.pluralize}_path", # rubocop:disable GitlabSecurity/PublicSend
58 59
                  subject.namespace,
                  subject,
60 61
                  label_name: [label.name])
    end
62 63
  end

64 65 66
  def edit_label_path(label)
    case label
    when GroupLabel then edit_group_label_path(label.group, label)
67
    when ProjectLabel then edit_project_label_path(label.project, label)
68 69 70 71 72 73
    end
  end

  def destroy_label_path(label)
    case label
    when GroupLabel then group_label_path(label.group, label)
74
    when ProjectLabel then project_label_path(label.project, label)
75 76 77
    end
  end

78
  def render_colored_label(label, label_suffix = '', tooltip: true)
79
    text_color = text_color_for_bg(label.color)
80

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

    span.html_safe
89
  end
90 91 92

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

  def text_color_for_bg(bg_color)
118 119 120 121 122
    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
123 124

    if (r + g + b) > 500
125
      '#333333'
126
    else
127
      '#FFFFFF'
128 129
    end
  end
130

Felipe Artur's avatar
Felipe Artur committed
131
  def labels_filter_path(only_group_labels = false)
132
    project = @target_project || @project
133

134
    if project
135
      project_labels_path(project, :json)
Felipe Artur's avatar
Felipe Artur committed
136 137 138
    elsif @group
      options = { only_group_labels: only_group_labels } if only_group_labels
      group_labels_path(@group, :json, options)
139
    else
140
      dashboard_labels_path(:json)
141
    end
142
  end
143

144
  def can_subscribe_to_label_in_different_levels?(label)
145
    defined?(@project) && label.is_a?(GroupLabel)
146 147
  end

148
  def label_subscription_status(label, project)
149
    return 'group-level' if label.subscribed?(current_user)
150
    return 'project-level' if label.subscribed?(current_user, project)
151 152 153 154

    'unsubscribed'
  end

155
  def toggle_subscription_label_path(label, project)
156 157 158 159
    return toggle_subscription_group_label_path(label.group, label) unless project

    case label_subscription_status(label, project)
    when 'group-level' then toggle_subscription_group_label_path(label.group, label)
160 161
    when 'project-level' then toggle_subscription_project_label_path(project, label)
    when 'unsubscribed' then toggle_subscription_project_label_path(project, label)
162 163 164
    end
  end

165
  def label_subscription_toggle_button_text(label, project = nil)
166
    label.subscribed?(current_user, project) ? 'Unsubscribe' : 'Subscribe'
167 168
  end

169 170 171 172 173 174 175
  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

176
  # Required for Banzai::Filter::LabelReferenceFilter
177
  module_function :render_colored_label, :text_color_for_bg, :escape_once
178
end