Issue macro supports comments and issue_id detection from url
This commit is contained in:
parent
0a0974a5a0
commit
221f89b371
@ -11,6 +11,7 @@ Changelog
|
||||
- Traditional Chinese support has been added (thanks to @archonwang)
|
||||
- Wiki macro for weather with meteoblue has been added
|
||||
- Wiki macro for google maps has been added
|
||||
- Wiki macro for issues now supports display a comment and detect issue id and comment id from URL
|
||||
|
||||
2.0.4
|
||||
+++++
|
||||
|
@ -3,22 +3,36 @@ Issue
|
||||
|
||||
Issue wiki macro for Redmine.
|
||||
|
||||
.. function:: {{issue(id [, format=FORMAT])}}
|
||||
.. function:: {{issue(URL [, format=FORMAT, id=ISSUE_ID, note_id=COMMENT_ID])}}
|
||||
|
||||
Display link to issue with subject
|
||||
|
||||
:param int id: issue id of the issue
|
||||
:param string url: URL to issue with issue id (and note_id)
|
||||
:param string format: custom format of link name. Possible values: full, text, short or link. If not specified 'link' is used as default.
|
||||
:param int id: issue id (if this is defined, it will be always used - and not from URL)
|
||||
:param int note_id: comment id (if this is defined, it will be always used - and not from URL)
|
||||
|
||||
Examples
|
||||
++++++++
|
||||
|
||||
Link to issue with subject and id
|
||||
Link to issue with id and subject
|
||||
|
||||
.. code-block:: smarty
|
||||
|
||||
{{issue(1)}}
|
||||
|
||||
Link to issue with id and subject
|
||||
|
||||
.. code-block:: smarty
|
||||
|
||||
{{issue(http://myredmine.url/issues/1)}}
|
||||
|
||||
Link to issue with id and subject and show comment 3
|
||||
|
||||
.. code-block:: smarty
|
||||
|
||||
{{issue(http://myredmine.url/issues/1#note-3)}}
|
||||
|
||||
Link to issue with subject (without id)
|
||||
|
||||
.. code-block:: smarty
|
||||
|
@ -18,6 +18,57 @@ module Additionals
|
||||
tabs
|
||||
end
|
||||
|
||||
def render_issue_macro_link(issue, text, comment_id = nil)
|
||||
content = link_to(text, issue_url(issue, only_path: true), class: issue.css_classes)
|
||||
if comment_id.nil?
|
||||
content
|
||||
else
|
||||
render_issue_with_comment(issue, content, comment_id)
|
||||
end
|
||||
end
|
||||
|
||||
def render_issue_with_comment(issue, content, comment_id)
|
||||
comment = issue.journals
|
||||
.where(private_notes: 0)
|
||||
.where.not(notes: '')
|
||||
.offset(comment_id - 1).limit(1).first.try(:notes)
|
||||
if comment.blank?
|
||||
comment = 'N/A'
|
||||
comment_link = comment_id
|
||||
else
|
||||
comment_link = link_to(comment_id, issue_url(issue, only_path: true, anchor: "note-#{comment_id}"))
|
||||
end
|
||||
|
||||
content_tag :div, class: 'issue-macro box' do
|
||||
content_tag(:div, safe_join([content, '-', l(:label_comment), comment_link], ' '), class: 'issue-macro-subject') +
|
||||
content_tag(:div, textilizable(comment), class: 'issue-macro-comment journal has-notes')
|
||||
end
|
||||
end
|
||||
|
||||
def parse_issue_url(url, comment_id = nil)
|
||||
rc = { issue_id: nil, comment_id: nil }
|
||||
if url.to_i.zero?
|
||||
uri = URI.parse(url)
|
||||
current_uri = URI.parse(request.original_url)
|
||||
return rc unless uri.host == current_uri.host
|
||||
s_pos = uri.path.rindex('/issues/')
|
||||
id_string = uri.path[s_pos + 8..-1]
|
||||
e_pos = id_string.index('/')
|
||||
rc[:issue_id] = if e_pos.nil?
|
||||
id_string
|
||||
else
|
||||
id_string[0..e_pos - 1]
|
||||
end
|
||||
# check for comment_id
|
||||
if comment_id.nil? && uri.fragment.present? && uri.fragment[0..4] == 'note-'
|
||||
rc[:comment_id] = uri.fragment[5..-1].to_i
|
||||
end
|
||||
else
|
||||
rc[:issue_id] = url
|
||||
end
|
||||
rc
|
||||
end
|
||||
|
||||
def additionals_library_load(module_name)
|
||||
method = "additionals_load_#{module_name}"
|
||||
send(method)
|
||||
|
@ -6,18 +6,24 @@ module Additionals
|
||||
Create a link to issue with the subject of this issue.
|
||||
Syntax:
|
||||
|
||||
{{issue(ID [, format=USER_FORMAT)}}
|
||||
ID is issue id
|
||||
{{issue(URL [, format=USER_FORMAT, id=ID, note_id=NOTE_ID)}}
|
||||
URL is URL to issue
|
||||
USER_FORMATS
|
||||
- text
|
||||
- short
|
||||
- link (default)
|
||||
- full
|
||||
ID is issue
|
||||
NOTE_ID is note id, if you want to display it
|
||||
|
||||
Examples:
|
||||
|
||||
{{issue(1)}}
|
||||
...Link to issue with subject and id
|
||||
...Link to issue with id and subject
|
||||
{{issue(http://myredmine.url/issues/1)}}
|
||||
...Link to issue with id and subject
|
||||
{{issue(http://myredmine.url/issues/1#note-3)}}
|
||||
...Link to issue with id and subject and display comment 3
|
||||
{{issue(1, format=short)}}
|
||||
...Link to issue with subject (without id)
|
||||
{{issue(1, format=text)}}
|
||||
@ -27,9 +33,19 @@ module Additionals
|
||||
DESCRIPTION
|
||||
|
||||
macro :issue do |_obj, args|
|
||||
args, options = extract_macro_options(args, :format)
|
||||
raise 'The correct usage is {{issue(<issue_id>, format=FORMAT)}}' if args.empty?
|
||||
issue_id = args[0]
|
||||
args, options = extract_macro_options(args, :id, :note_id, :format)
|
||||
if args.empty? && options[:id].blank?
|
||||
raise 'The correct usage is {{issue(<url>, format=FORMAT, id=INT, note_id=INT)}}'
|
||||
end
|
||||
|
||||
comment_id = options[:note_id].to_i if options[:note_id].present?
|
||||
issue_id = if options[:id].blank?
|
||||
info = parse_issue_url(args[0], comment_id)
|
||||
comment_id = info[:comment_id] if comment_id.nil?
|
||||
info[:issue_id]
|
||||
else
|
||||
options[:id]
|
||||
end
|
||||
|
||||
issue = Issue.find_by(id: issue_id)
|
||||
return 'N/A' if issue.nil? || !issue.visible?
|
||||
@ -40,11 +56,11 @@ module Additionals
|
||||
when 'text', 'short'
|
||||
issue.subject
|
||||
else
|
||||
"#{issue.subject} ##{issue.id}"
|
||||
"##{issue.id} #{issue.subject}"
|
||||
end
|
||||
|
||||
if options[:format].blank? || options[:format] != 'text'
|
||||
link_to(text, issue_url(issue, only_path: true), class: issue.css_classes)
|
||||
render_issue_macro_link(issue, text, comment_id)
|
||||
else
|
||||
text
|
||||
end
|
||||
|
@ -36,11 +36,7 @@ module Additionals
|
||||
end
|
||||
|
||||
def self.load_projects
|
||||
all_projects = if ActiveRecord::VERSION::MAJOR < 4
|
||||
Project.active.visible(User.current).find(:all, order: 'projects.name')
|
||||
else
|
||||
Project.active.visible.sorted
|
||||
end
|
||||
all_projects = Project.active.visible.sorted
|
||||
my_projects = []
|
||||
all_projects.each do |p|
|
||||
my_projects << p if User.current.member_of?(p)
|
||||
|
@ -1,7 +1,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
# Additionals integration tests
|
||||
class CommonViewsTest < ActiveRecord::VERSION::MAJOR >= 4 ? Redmine::ApiTest::Base : ActionController::IntegrationTest
|
||||
class CommonViewsTest < Redmine::IntegrationTest
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:roles,
|
||||
|
@ -38,11 +38,7 @@ module Additionals
|
||||
end
|
||||
|
||||
def self.create_fixtures(fixtures_directory, table_names, _class_names = {})
|
||||
if ActiveRecord::VERSION::MAJOR >= 4
|
||||
ActiveRecord::FixtureSet.create_fixtures(fixtures_directory, table_names, _class_names = {})
|
||||
else
|
||||
ActiveRecord::Fixtures.create_fixtures(fixtures_directory, table_names, _class_names = {})
|
||||
end
|
||||
ActiveRecord::FixtureSet.create_fixtures(fixtures_directory, table_names, _class_names = {})
|
||||
end
|
||||
|
||||
def self.prepare
|
||||
|
Loading…
x
Reference in New Issue
Block a user