issues_helper.rb 5.07 KB
Newer Older
gitlabhq's avatar
gitlabhq committed
1
module IssuesHelper
2
  def issue_css_classes(issue)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
3
    classes = "issue"
Andrew8xx8's avatar
Andrew8xx8 committed
4
    classes << " closed" if issue.closed?
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
5 6 7
    classes << " today" if issue.today?
    classes
  end
8

9 10 11 12
  # 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
13
    OpenStruct.new(id: 0, title: 'None (backlog)', name: 'Unassigned')
14
  end
15

16
  def url_for_issue(issue_iid, project = @project, options = {})
skv's avatar
skv committed
17
    return '' if project.nil?
Andrew8xx8's avatar
Andrew8xx8 committed
18

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

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

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
  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

50
  def bulk_update_milestone_options
51
    milestones = @project.milestones.active.reorder(due_date: :asc, title: :asc).to_a
52 53 54
    milestones.unshift(Milestone::None)

    options_from_collection_for_select(milestones, 'id', 'title', params[:milestone_id])
55 56
  end

57
  def milestone_options(object)
58
    milestones = object.project.milestones.active.reorder(due_date: :asc, title: :asc).to_a
59
    milestones.unshift(object.milestone) if object.milestone.present? && object.milestone.closed?
60 61 62
    milestones.unshift(Milestone::None)

    options_from_collection_for_select(milestones, 'id', 'title', object.milestone_id)
63
  end
64

65 66 67
  def project_options(issuable, current_user, ability: :read_project)
    projects = current_user.authorized_projects
    projects = projects.select do |project|
68
      current_user.can?(ability, project)
69 70
    end

71 72 73
    no_project = OpenStruct.new(id: 0, name_with_namespace: 'No project')
    projects.unshift(no_project)
    projects.delete(issuable.project)
74

75
    options_from_collection_for_select(projects, :id, :name_with_namespace)
76 77
  end

78
  def status_box_class(item)
79
    if item.try(:expired?)
80
      'status-box-expired'
81
    elsif item.try(:merged?)
82
      'status-box-merged'
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
83
    elsif item.closed?
84
      'status-box-closed'
85
    elsif item.try(:upcoming?)
86
      'status-box-upcoming'
87
    else
88
      'status-box-open'
89 90
    end
  end
91

92
  def issue_button_visibility(issue, closed)
93 94 95
    return 'hidden' if issue.closed? == closed
  end

96
  def merge_requests_sentence(merge_requests)
97 98 99 100 101
    # Sorting based on the `!123` or `group/project!123` reference will sort
    # local merge requests first.
    merge_requests.map do |merge_request|
      merge_request.to_reference(@project)
    end.sort.to_sentence(last_word_connector: ', or ')
102 103
  end

104 105 106 107
  def confidential_icon(issue)
    icon('eye-slash') if issue.confidential?
  end

108
  def award_user_list(awards, current_user, limit: 10)
109
    names = awards.map do |award|
110
      award.user == current_user ? 'You' : award.user.name
111 112
    end

113
    current_user_name = names.delete('You')
114
    names = names.insert(0, current_user_name).compact.first(limit)
115

116
    names << "#{awards.size - names.size} more." if awards.size > names.size
117

118
    names.to_sentence
Valery Sizov's avatar
Valery Sizov committed
119 120
  end

121 122 123 124
  def award_state_class(awards, current_user)
    if !current_user
      "disabled"
    elsif current_user && awards.find { |a| a.user_id == current_user.id }
Valery Sizov's avatar
Valery Sizov committed
125 126 127 128
      "active"
    else
      ""
    end
Valery Sizov's avatar
Valery Sizov committed
129 130
  end

barthc's avatar
barthc committed
131 132 133 134 135 136 137 138
  def award_user_authored_class(award)
    if award == 'thumbsdown' || award == 'thumbsup'
      'user-authored js-user-authored'
    else
      ''
    end
  end

Valery Sizov's avatar
Valery Sizov committed
139 140 141 142 143 144 145 146 147 148 149 150
  def awards_sort(awards)
    awards.sort_by do |award, notes|
      if award == "thumbsup"
        0
      elsif award == "thumbsdown"
        1
      else
        2
      end
    end.to_h
  end

151 152
  def due_date_options
    options = [
Rémy Coutable's avatar
Rémy Coutable committed
153 154 155 156 157
      Issue::AnyDueDate,
      Issue::NoDueDate,
      Issue::DueThisWeek,
      Issue::DueThisMonth,
      Issue::Overdue
158
    ]
159 160

    options_from_collection_for_select(options, 'name', 'title', params[:due_date])
161 162
  end

163
  def link_to_discussions_to_resolve(merge_request, single_discussion = nil)
164 165 166 167 168 169 170
    link_text = merge_request.to_reference
    link_text += " (discussion #{single_discussion.first_note.id})" if single_discussion

    path = if single_discussion
             Gitlab::UrlBuilder.build(single_discussion.first_note)
           else
             project = merge_request.project
171
             project_merge_request_path(project, merge_request)
172 173 174 175 176
           end

    link_to link_text, path
  end

177
  # Required for Banzai::Filter::IssueReferenceFilter
178
  module_function :url_for_issue
179 180
  module_function :url_for_internal_issue
  module_function :url_for_tracker_issue
gitlabhq's avatar
gitlabhq committed
181
end