issuables_helper.rb 6.2 KB
Newer Older
1 2 3 4 5 6 7 8 9
module IssuablesHelper
  def sidebar_gutter_toggle_icon
    sidebar_gutter_collapsed? ? icon('angle-double-left') : icon('angle-double-right')
  end

  def sidebar_gutter_collapsed_class
    "right-sidebar-#{sidebar_gutter_collapsed? ? 'collapsed' : 'expanded'}"
  end

10
  def multi_label_name(current_labels, default_label)
11
    if current_labels && current_labels.any?
12
      title = current_labels.first.try(:title)
13 14
      if current_labels.size > 1
        "#{title} +#{current_labels.size - 1} more"
J
Jacob Schatz 已提交
15
      else
16
        title
J
Jacob Schatz 已提交
17
      end
A
Arinde Eniola 已提交
18
    else
19
      default_label
J
Jacob Schatz 已提交
20 21 22
    end
  end

J
Jacob Schatz 已提交
23 24 25 26 27 28 29 30 31 32
  def issuable_json_path(issuable)
    project = issuable.project

    if issuable.kind_of?(MergeRequest)
      namespace_project_merge_request_path(project.namespace, project, issuable.iid, :json)
    else
      namespace_project_issue_path(project.namespace, project, issuable.iid, :json)
    end
  end

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
  def can_add_template?(issuable)
    names = issuable_templates(issuable)
    names.empty? && can?(current_user, :push_code, @project) && !@project.private?
  end

  def template_dropdown_tag(issuable, &block)
    title = selected_template(issuable) || "Choose a template"
    options = {
      toggle_class: 'js-issuable-selector',
      title: title,
      filter: true,
      placeholder: 'Filter',
      footer_content: true,
      data: {
        data: issuable_templates(issuable),
        field_name: 'issuable_template',
        selected: selected_template(issuable),
        project_path: ref_project.path,
        namespace_path: ref_project.namespace.path
      }
    }

    dropdown_tag(title, options: options) do
      capture(&block)
    end
  end

60
  def user_dropdown_label(user_id, default_label)
P
Phil Hughes 已提交
61
    return default_label if user_id.nil?
62 63
    return "Unassigned" if user_id == "0"

P
Phil Hughes 已提交
64
    user = User.find_by(id: user_id)
65 66 67 68 69 70 71 72

    if user
      user.name
    else
      default_label
    end
  end

73 74 75 76 77 78 79
  def project_dropdown_label(project_id, default_label)
    return default_label if project_id.nil?
    return "Any project" if project_id == "0"

    project = Project.find_by(id: project_id)

    if project
80
      project.name_with_namespace
81 82 83 84 85
    else
      default_label
    end
  end

P
Phil Hughes 已提交
86
  def milestone_dropdown_label(milestone_title, default_label = "Milestone")
P
Phil Hughes 已提交
87 88
    if milestone_title == Milestone::Upcoming.name
      milestone_title = Milestone::Upcoming.title
89
    end
P
Phil Hughes 已提交
90 91

    h(milestone_title.presence || default_label)
92 93
  end

94 95
  def issuable_meta(issuable, project, text)
    output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier"
96
    output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
97
    output << content_tag(:strong) do
98
      author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs", tooltip: true)
99 100
      author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg")
    end
101 102 103 104 105 106 107 108

    if issuable.tasks?
      output << "&ensp;".html_safe
      output << content_tag(:span, issuable.task_status, id: "task_status", class: "hidden-xs")
      output << content_tag(:span, issuable.task_status_short, id: "task_status_short", class: "hidden-sm hidden-md hidden-lg")
    end

    output
109 110
  end

P
Phil Hughes 已提交
111
  def issuable_todo(issuable)
112
    if current_user
P
Phil Hughes 已提交
113
      current_user.todos.find_by(target: issuable, state: :pending)
114
    end
P
Phil Hughes 已提交
115 116
  end

P
Phil Hughes 已提交
117
  def issuable_labels_tooltip(labels, limit: 5)
P
Phil Hughes 已提交
118
    first, last = labels.partition.with_index{ |_, i| i < limit  }
119

P
Phil Hughes 已提交
120 121
    label_names = first.collect(&:name)
    label_names << "and #{last.size} more" unless last.empty?
122

P
Phil Hughes 已提交
123
    label_names.join(', ')
124 125
  end

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  def issuables_state_counter_text(issuable_type, state)
    titles = {
      opened: "Open"
    }

    state_title = titles[state] || state.to_s.humanize

    count =
      Rails.cache.fetch(issuables_state_counter_cache_key(issuable_type, state), expires_in: 2.minutes) do
        issuables_count_for_state(issuable_type, state)
      end

    html = content_tag(:span, state_title)
    html << " " << content_tag(:span, number_with_delimiter(count), class: 'badge')

    html.html_safe
  end

144 145 146 147 148 149 150
  def cached_assigned_issuables_count(assignee, issuable_type, state)
    cache_key = "#{assignee.id}_#{issuable_type}_#{state}"
    Rails.cache.fetch(cache_key, expires_in: 2.minutes) do
      assigned_issuables_count(assignee, issuable_type, state)
    end
  end

151 152
  private

153 154 155 156
  def assigned_issuables_count(assignee, issuable_type, state)
    assignee.send("assigned_#{issuable_type}").send(state).count
  end

157 158 159 160 161
  def sidebar_gutter_collapsed?
    cookies[:collapsed_gutter] == 'true'
  end

  def base_issuable_scope(issuable)
162
    issuable.project.send(issuable.class.table_name).send(issuable_state_scope(issuable))
163 164 165
  end

  def issuable_state_scope(issuable)
166 167 168 169 170
    if issuable.respond_to?(:merged?) && issuable.merged?
      :merged
    else
      issuable.open? ? :opened : :closed
    end
171
  end
172

173 174 175 176
  def issuable_filters_present
    params[:search] || params[:author_id] || params[:assignee_id] || params[:milestone_title] || params[:label_name]
  end

177 178 179 180 181 182 183
  def issuables_count_for_state(issuable_type, state)
    issuables_finder = public_send("#{issuable_type}_finder")
    issuables_finder.params[:state] = state

    issuables_finder.execute.page(1).total_count
  end

184
  IRRELEVANT_PARAMS_FOR_CACHE_KEY = %i[utf8 sort page]
185 186 187
  private_constant :IRRELEVANT_PARAMS_FOR_CACHE_KEY

  def issuables_state_counter_cache_key(issuable_type, state)
188 189 190
    opts = params.with_indifferent_access
    opts[:state] = state
    opts.except!(*IRRELEVANT_PARAMS_FOR_CACHE_KEY)
191 192 193

    hexdigest(['issuables_count', issuable_type, opts.sort].flatten.join('-'))
  end
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217

  def issuable_templates(issuable)
    @issuable_templates ||=
      case issuable
      when Issue
        issue_template_names
      when MergeRequest
        merge_request_template_names
      else
        raise 'Unknown issuable type!'
      end
  end

  def merge_request_template_names
    @merge_request_templates ||= Gitlab::Template::MergeRequestTemplate.dropdown_names(ref_project)
  end

  def issue_template_names
    @issue_templates ||= Gitlab::Template::IssueTemplate.dropdown_names(ref_project)
  end

  def selected_template(issuable)
    params[:issuable_template] if issuable_templates(issuable).include?(params[:issuable_template])
  end
218
end