issues_helper.rb 4.46 KB
Newer Older
1 2
# frozen_string_literal: true

gitlabhq's avatar
gitlabhq committed
3
module IssuesHelper
4
  def issue_css_classes(issue)
5 6 7
    classes = ["issue"]
    classes << "closed" if issue.closed?
    classes << "today" if issue.today?
8
    classes << "user-can-drag" if @sort == 'relative_position'
9
    classes.join(' ')
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
10
  end
11

12 13 14 15
  # Returns an OpenStruct object suitable for use by <tt>options_from_collection_for_select</tt>
  # to allow filtering issues by an unassigned User or Milestone
  def unassigned_filter
    # Milestone uses :title, Issue uses :name
16
    OpenStruct.new(id: 0, title: 'None (backlog)', name: 'Unassigned')
17
  end
18

19
  def url_for_issue(issue_iid, project = @project, options = {})
skv's avatar
skv committed
20
    return '' if project.nil?
Andrew8xx8's avatar
Andrew8xx8 committed
21

22
    url =
23 24
      if options[:internal]
        url_for_internal_issue(issue_iid, project, options)
25
      else
26
        url_for_tracker_issue(issue_iid, project, options)
27 28 29 30 31 32
      end

    # Ensure we return a valid URL to prevent possible XSS.
    URI.parse(url).to_s
  rescue URI::InvalidURIError
    ''
33 34
  end

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
  def url_for_tracker_issue(issue_iid, project, options)
    if options[:only_path]
      project.issues_tracker.issue_path(issue_iid)
    else
      project.issues_tracker.issue_url(issue_iid)
    end
  end

  def url_for_internal_issue(issue_iid, project = @project, options = {})
    helpers = Gitlab::Routing.url_helpers

    if options[:only_path]
      helpers.namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: issue_iid)
    else
      helpers.namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: issue_iid)
    end
  end

53
  def status_box_class(item)
54
    if item.try(:expired?)
55
      'status-box-expired'
56
    elsif item.try(:merged?)
57
      'status-box-mr-merged'
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
58
    elsif item.closed?
59
      'status-box-mr-closed'
60
    elsif item.try(:upcoming?)
61
      'status-box-upcoming'
62
    else
63
      'status-box-open'
64 65
    end
  end
66

67
  def issue_button_visibility(issue, closed)
68 69 70 71 72
    return 'hidden' if issue_button_hidden?(issue, closed)
  end

  def issue_button_hidden?(issue, closed)
    issue.closed? == closed || (!closed && issue.discussion_locked)
73 74
  end

75 76 77 78
  def confidential_icon(issue)
    icon('eye-slash') if issue.confidential?
  end

79
  def award_user_list(awards, current_user, limit: 10)
80
    names = awards.map do |award|
81
      award.user == current_user ? 'You' : award.user.name
82 83
    end

84
    current_user_name = names.delete('You')
85
    names = names.insert(0, current_user_name).compact.first(limit)
86

87
    names << "#{awards.size - names.size} more." if awards.size > names.size
88

89
    names.to_sentence
Valery Sizov's avatar
Valery Sizov committed
90 91
  end

92 93
  def award_state_class(awardable, awards, current_user)
    if !can?(current_user, :award_emoji, awardable)
94 95
      "disabled"
    elsif current_user && awards.find { |a| a.user_id == current_user.id }
Valery Sizov's avatar
Valery Sizov committed
96 97 98 99
      "active"
    else
      ""
    end
Valery Sizov's avatar
Valery Sizov committed
100 101
  end

Valery Sizov's avatar
Valery Sizov committed
102
  def awards_sort(awards)
103
    awards.sort_by do |award, award_emojis|
Valery Sizov's avatar
Valery Sizov committed
104 105 106 107 108 109 110 111 112 113
      if award == "thumbsup"
        0
      elsif award == "thumbsdown"
        1
      else
        2
      end
    end.to_h
  end

114
  def link_to_discussions_to_resolve(merge_request, single_discussion = nil)
115 116
    link_text = [merge_request.to_reference]
    link_text << "(discussion #{single_discussion.first_note.id})" if single_discussion
117 118 119 120 121

    path = if single_discussion
             Gitlab::UrlBuilder.build(single_discussion.first_note)
           else
             project = merge_request.project
122
             project_merge_request_path(project, merge_request)
123 124
           end

125
    link_to link_text.join(' '), path
126 127
  end

128 129 130 131 132 133 134 135 136 137 138
  def show_new_issue_link?(project)
    return false unless project
    return false if project.archived?

    # We want to show the link to users that are not signed in, that way they
    # get directed to the sign-in/sign-up flow and afterwards to the new issue page.
    return true unless current_user

    can?(current_user, :create_issue, project)
  end

139
  def create_confidential_merge_request_enabled?
140
    Feature.enabled?(:create_confidential_merge_request, @project, default_enabled: true)
141 142 143 144 145 146 147 148 149 150 151 152
  end

  def show_new_branch_button?
    can_create_confidential_merge_request? || !@issue.confidential?
  end

  def can_create_confidential_merge_request?
    @issue.confidential? && !@project.private? &&
      create_confidential_merge_request_enabled? &&
      can?(current_user, :create_merge_request_in, @project)
  end

153
  # Required for Banzai::Filter::IssueReferenceFilter
154
  module_function :url_for_issue
155 156
  module_function :url_for_internal_issue
  module_function :url_for_tracker_issue
gitlabhq's avatar
gitlabhq committed
157
end
158 159

IssuesHelper.include(EE::IssuesHelper)