Commit f881e4367753075bbdbfaca1ea83a6ef80549b72

Authored by Dmitriy Zaporozhets
2 parents f82d0d8d 9c046fea

Merge pull request #7024 from skv-headless/linkto_issues_on_main_dashboard

links to issues on main dashboard
app/helpers/gitlab_markdown_helper.rb
... ... @@ -19,7 +19,7 @@ module GitlabMarkdownHelper
19 19 escape_once(body)
20 20 end
21 21  
22   - gfm_body = gfm(escaped_body, html_options)
  22 + gfm_body = gfm(escaped_body, @project, html_options)
23 23  
24 24 gfm_body.gsub!(%r{<a.*?>.*?</a>}m) do |match|
25 25 "</a>#{match}#{link_to("", url, html_options)[0..-5]}" # "</a>".length +1
... ...
app/helpers/issues_helper.rb
... ... @@ -13,76 +13,80 @@ module IssuesHelper
13 13 OpenStruct.new(id: 0, title: 'None (backlog)', name: 'Unassigned')
14 14 end
15 15  
16   - def url_for_project_issues
17   - return "" if @project.nil?
  16 + def url_for_project_issues(project = @project)
  17 + return '' if project.nil?
18 18  
19   - if @project.used_default_issues_tracker? || !external_issues_tracker_enabled?
20   - project_issues_path(@project)
  19 + if project.used_default_issues_tracker? || !external_issues_tracker_enabled?
  20 + project_issues_path(project)
21 21 else
22   - url = Gitlab.config.issues_tracker[@project.issues_tracker]["project_url"]
23   - url.gsub(':project_id', @project.id.to_s)
24   - .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s)
  22 + url = Gitlab.config.issues_tracker[project.issues_tracker]['project_url']
  23 + url.gsub(':project_id', project.id.to_s).
  24 + gsub(':issues_tracker_id', project.issues_tracker_id.to_s)
25 25 end
26 26 end
27 27  
28   - def url_for_new_issue
29   - return "" if @project.nil?
  28 + def url_for_new_issue(project = @project)
  29 + return '' if project.nil?
30 30  
31   - if @project.used_default_issues_tracker? || !external_issues_tracker_enabled?
32   - url = new_project_issue_path project_id: @project
  31 + if project.used_default_issues_tracker? || !external_issues_tracker_enabled?
  32 + url = new_project_issue_path project_id: project
33 33 else
34   - url = Gitlab.config.issues_tracker[@project.issues_tracker]["new_issue_url"]
35   - url.gsub(':project_id', @project.id.to_s)
36   - .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s)
  34 + issues_tracker = Gitlab.config.issues_tracker[project.issues_tracker]
  35 + url = issues_tracker['new_issue_url']
  36 + url.gsub(':project_id', project.id.to_s).
  37 + gsub(':issues_tracker_id', project.issues_tracker_id.to_s)
37 38 end
38 39 end
39 40  
40   - def url_for_issue(issue_iid)
41   - return "" if @project.nil?
  41 + def url_for_issue(issue_iid, project = @project)
  42 + return '' if project.nil?
42 43  
43   - if @project.used_default_issues_tracker? || !external_issues_tracker_enabled?
44   - url = project_issue_url project_id: @project, id: issue_iid
  44 + if project.used_default_issues_tracker? || !external_issues_tracker_enabled?
  45 + url = project_issue_url project_id: project, id: issue_iid
45 46 else
46   - url = Gitlab.config.issues_tracker[@project.issues_tracker]["issues_url"]
47   - url.gsub(':id', issue_iid.to_s)
48   - .gsub(':project_id', @project.id.to_s)
49   - .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s)
  47 + url = Gitlab.config.issues_tracker[project.issues_tracker]['issues_url']
  48 + url.gsub(':id', issue_iid.to_s).
  49 + gsub(':project_id', project.id.to_s).
  50 + gsub(':issues_tracker_id', project.issues_tracker_id.to_s)
50 51 end
51 52 end
52 53  
53   - def title_for_issue(issue_iid)
54   - return "" if @project.nil?
  54 + def title_for_issue(issue_iid, project = @project)
  55 + return '' if project.nil?
55 56  
56   - if @project.used_default_issues_tracker? && issue = @project.issues.where(iid: issue_iid).first
57   - issue.title
58   - else
59   - ""
  57 + if project.used_default_issues_tracker?
  58 + issue = project.issues.where(iid: issue_iid).first
  59 + return issue.title if issue
60 60 end
  61 +
  62 + ''
61 63 end
62 64  
63 65 # Checks if issues_tracker setting exists in gitlab.yml
64 66 def external_issues_tracker_enabled?
65   - if Gitlab.config.issues_tracker && Gitlab.config.issues_tracker.values.any?
66   - true
67   - else
68   - false
69   - end
  67 + Gitlab.config.issues_tracker && Gitlab.config.issues_tracker.values.any?
70 68 end
71 69  
72 70 def bulk_update_milestone_options
73   - options_for_select(["None (backlog)"]) + options_from_collection_for_select(project_active_milestones, "id", "title", params[:milestone_id])
  71 + options_for_select(['None (backlog)']) +
  72 + options_from_collection_for_select(project_active_milestones, 'id',
  73 + 'title', params[:milestone_id])
74 74 end
75 75  
76   - def bulk_update_assignee_options
77   - options_for_select(["None (unassigned)"]) + options_from_collection_for_select(@project.team.members, "id", "name", params[:assignee_id])
  76 + def bulk_update_assignee_options(project = @project)
  77 + options_for_select(['None (unassigned)']) +
  78 + options_from_collection_for_select(project.team.members, 'id',
  79 + 'name', params[:assignee_id])
78 80 end
79 81  
80   - def assignee_options object
81   - options_from_collection_for_select(@project.team.members.sort_by(&:name), 'id', 'name', object.assignee_id)
  82 + def assignee_options(object, project = @project)
  83 + options_from_collection_for_select(project.team.members.sort_by(&:name),
  84 + 'id', 'name', object.assignee_id)
82 85 end
83 86  
84 87 def milestone_options object
85   - options_from_collection_for_select(object.project.milestones.active, 'id', 'title', object.milestone_id)
  88 + options_from_collection_for_select(object.project.milestones.active,
  89 + 'id', 'title', object.milestone_id)
86 90 end
87 91  
88 92 def issue_box_class(item)
... ...
app/views/events/_commit.html.haml
... ... @@ -2,4 +2,4 @@
2 2 .commit-row-title
3 3 = link_to commit[:id][0..8], project_commit_path(project, commit[:id]), class: "commit_short_id", alt: ''
4 4 &nbsp;
5   - = gfm event_commit_title(commit[:message])
  5 + = gfm event_commit_title(commit[:message]), project
... ...
lib/gitlab/markdown.rb
... ... @@ -33,10 +33,9 @@ module Gitlab
33 33 # Public: Parse the provided text with GitLab-Flavored Markdown
34 34 #
35 35 # text - the source text
  36 + # project - extra options for the reference links as given to link_to
36 37 # html_options - extra options for the reference links as given to link_to
37   - #
38   - # Note: reference links will only be generated if @project is set
39   - def gfm(text, html_options = {})
  38 + def gfm(text, project = @project, html_options = {})
40 39 return text if text.nil?
41 40  
42 41 # Duplicate the string so we don't alter the original, then call to_str
... ... @@ -56,14 +55,19 @@ module Gitlab
56 55  
57 56 # TODO: add popups with additional information
58 57  
59   - text = parse(text)
  58 + text = parse(text, project)
60 59  
61 60 # Insert pre block extractions
62 61 text.gsub!(/\{gfm-extraction-(\h{32})\}/) do
63 62 insert_piece($1)
64 63 end
65 64  
66   - sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class), tags: ActionView::Base.sanitized_allowed_tags + %w(table tr td th)
  65 + allowed_attributes = ActionView::Base.sanitized_allowed_attributes
  66 + allowed_tags = ActionView::Base.sanitized_allowed_tags
  67 +
  68 + sanitize text.html_safe,
  69 + attributes: allowed_attributes + %w(id class),
  70 + tags: allowed_tags + %w(table tr td th)
67 71 end
68 72  
69 73 private
... ... @@ -84,11 +88,9 @@ module Gitlab
84 88 #
85 89 # text - Text to parse
86 90 #
87   - # Note: reference links will only be generated if @project is set
88   - #
89 91 # Returns parsed text
90   - def parse(text)
91   - parse_references(text) if @project
  92 + def parse(text, project = @project)
  93 + parse_references(text, project) if project
92 94 parse_emoji(text)
93 95  
94 96 text
... ... @@ -110,7 +112,7 @@ module Gitlab
110 112  
111 113 TYPES = [:user, :issue, :merge_request, :snippet, :commit].freeze
112 114  
113   - def parse_references(text)
  115 + def parse_references(text, project = @project)
114 116 # parse reference links
115 117 text.gsub!(REFERENCE_PATTERN) do |match|
116 118 prefix = $~[:prefix]
... ... @@ -123,7 +125,7 @@ module Gitlab
123 125 # Avoid HTML entities
124 126 if prefix && suffix && prefix[0] == '&' && suffix[-1] == ';'
125 127 match
126   - elsif ref_link = reference_link(type, identifier)
  128 + elsif ref_link = reference_link(type, identifier, project)
127 129 "#{prefix}#{ref_link}#{suffix}"
128 130 else
129 131 match
... ... @@ -153,7 +155,7 @@ module Gitlab
153 155 #
154 156 # Returns boolean
155 157 def valid_emoji?(emoji)
156   - Emoji.find_by_name emoji
  158 + Emoji.find_by_name(emoji)
157 159 end
158 160  
159 161 # Private: Dispatches to a dedicated processing method based on reference
... ... @@ -162,52 +164,77 @@ module Gitlab
162 164 # identifier - Object identifier (Issue ID, SHA hash, etc.)
163 165 #
164 166 # Returns string rendered by the processing method
165   - def reference_link(type, identifier)
166   - send("reference_#{type}", identifier)
  167 + def reference_link(type, identifier, project = @project)
  168 + send("reference_#{type}", identifier, project)
167 169 end
168 170  
169   - def reference_user(identifier)
170   - if user = User.find_by_username(identifier)
171   - link_to("@#{identifier}", user_url(identifier), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}"))
  171 + def reference_user(identifier, project = @project)
  172 + if user = User.find_by(username: identifier)
  173 + options = html_options.merge(
  174 + class: "gfm gfm-team_member #{html_options[:class]}"
  175 + )
  176 + link_to("@#{identifier}", user_url(identifier), options)
172 177 end
173 178 end
174 179  
175   - def reference_issue(identifier)
176   - if @project.used_default_issues_tracker? || !external_issues_tracker_enabled?
177   - if @project.issue_exists? identifier
178   - url = url_for_issue(identifier)
  180 + def reference_issue(identifier, project = @project)
  181 + if project.used_default_issues_tracker? || !external_issues_tracker_enabled?
  182 + if project.issue_exists? identifier
  183 + url = url_for_issue(identifier, project)
179 184 title = title_for_issue(identifier)
  185 + options = html_options.merge(
  186 + title: "Issue: #{title}",
  187 + class: "gfm gfm-issue #{html_options[:class]}"
  188 + )
180 189  
181   - link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
  190 + link_to("##{identifier}", url, options)
182 191 end
183   - else
184   - reference_jira_issue(identifier) if @project.issues_tracker == "jira"
  192 + elsif project.issues_tracker == 'jira'
  193 + reference_jira_issue(identifier, project)
185 194 end
186 195 end
187 196  
188   - def reference_merge_request(identifier)
189   - if merge_request = @project.merge_requests.where(iid: identifier).first
190   - link_to("!#{identifier}", project_merge_request_url(@project, merge_request), html_options.merge(title: "Merge Request: #{merge_request.title}", class: "gfm gfm-merge_request #{html_options[:class]}"))
  197 + def reference_merge_request(identifier, project = @project)
  198 + if merge_request = project.merge_requests.find_by(iid: identifier)
  199 + options = html_options.merge(
  200 + title: "Merge Request: #{merge_request.title}",
  201 + class: "gfm gfm-merge_request #{html_options[:class]}"
  202 + )
  203 + url = project_merge_request_url(project, merge_request)
  204 + link_to("!#{identifier}", url, options)
191 205 end
192 206 end
193 207  
194   - def reference_snippet(identifier)
195   - if snippet = @project.snippets.where(id: identifier).first
196   - link_to("$#{identifier}", project_snippet_url(@project, snippet), html_options.merge(title: "Snippet: #{snippet.title}", class: "gfm gfm-snippet #{html_options[:class]}"))
  208 + def reference_snippet(identifier, project = @project)
  209 + if snippet = project.snippets.find_by(id: identifier)
  210 + options = html_options.merge(
  211 + title: "Snippet: #{snippet.title}",
  212 + class: "gfm gfm-snippet #{html_options[:class]}"
  213 + )
  214 + link_to("$#{identifier}", project_snippet_url(project, snippet),
  215 + options)
197 216 end
198 217 end
199 218  
200   - def reference_commit(identifier)
201   - if @project.valid_repo? && commit = @project.repository.commit(identifier)
202   - link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}"))
  219 + def reference_commit(identifier, project = @project)
  220 + if project.valid_repo? && commit = project.repository.commit(identifier)
  221 + options = html_options.merge(
  222 + title: commit.link_title,
  223 + class: "gfm gfm-commit #{html_options[:class]}"
  224 + )
  225 + link_to(identifier, project_commit_url(project, commit), options)
203 226 end
204 227 end
205 228  
206   - def reference_jira_issue(identifier)
  229 + def reference_jira_issue(identifier, project = @project)
207 230 url = url_for_issue(identifier)
208 231 title = Gitlab.config.issues_tracker[@project.issues_tracker]["title"]
209 232  
210   - link_to("#{identifier}", url, html_options.merge(title: "Issue in #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
  233 + options = html_options.merge(
  234 + title: "Issue in #{title}",
  235 + class: "gfm gfm-issue #{html_options[:class]}"
  236 + )
  237 + link_to("#{identifier}", url, options)
211 238 end
212 239 end
213 240 end
... ...
lib/gitlab/reference_extractor.rb
... ... @@ -51,7 +51,7 @@ module Gitlab
51 51  
52 52 private
53 53  
54   - def reference_link type, identifier
  54 + def reference_link(type, identifier, project)
55 55 # Append identifier to the appropriate collection.
56 56 send("#{type}s") << identifier
57 57 end
... ...
spec/helpers/gitlab_markdown_helper_spec.rb
... ... @@ -41,7 +41,8 @@ describe GitlabMarkdownHelper do
41 41 end
42 42  
43 43 it "should forward HTML options to links" do
44   - gfm("Fixed in #{commit.id}", class: "foo").should have_selector("a.gfm.foo")
  44 + gfm("Fixed in #{commit.id}", @project, class: 'foo').
  45 + should have_selector('a.gfm.foo')
45 46 end
46 47  
47 48 describe "referencing a commit" do
... ...