additional_tags 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/brakeman.yml +38 -0
- data/.github/workflows/linters.yml +41 -0
- data/.github/workflows/tests.yml +139 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +75 -0
- data/.slim-lint.yml +25 -0
- data/.stylelintrc.json +163 -0
- data/LICENSE +339 -0
- data/README.md +126 -0
- data/Rakefile +11 -0
- data/additional_tags.gemspec +28 -0
- data/app/controllers/additional_tags_controller.rb +80 -0
- data/app/controllers/issue_tags_controller.rb +48 -0
- data/app/helpers/additional_tags_helper.rb +197 -0
- data/app/helpers/additional_tags_issues_helper.rb +43 -0
- data/app/helpers/additional_tags_wiki_helper.rb +17 -0
- data/app/jobs/additional_tags_job.rb +3 -0
- data/app/jobs/additional_tags_remove_unused_tag_job.rb +5 -0
- data/app/models/migrate_tag.rb +4 -0
- data/app/models/migrate_tagging.rb +5 -0
- data/app/views/additional_tags/_html_head.html.slim +6 -0
- data/app/views/additional_tags/_tag_list.html.slim +35 -0
- data/app/views/additional_tags/context_menu.html.slim +16 -0
- data/app/views/additional_tags/edit.html.slim +14 -0
- data/app/views/additional_tags/merge.html.slim +17 -0
- data/app/views/additional_tags/settings/_general.html.slim +45 -0
- data/app/views/additional_tags/settings/_manage_tags.html.slim +35 -0
- data/app/views/additional_tags/settings/_settings.html.slim +9 -0
- data/app/views/auto_completes/_additional_tag_list.slim +1 -0
- data/app/views/context_menus/_issues_tags.html.slim +10 -0
- data/app/views/issue_tags/_edit_modal.html.slim +30 -0
- data/app/views/issue_tags/edit.js.erb +2 -0
- data/app/views/issues/_tags.html.slim +8 -0
- data/app/views/issues/_tags_bulk_edit.html.slim +7 -0
- data/app/views/issues/_tags_form.html.slim +11 -0
- data/app/views/issues/_tags_form_details.html.slim +7 -0
- data/app/views/issues/_tags_sidebar.html.slim +5 -0
- data/app/views/reports/_tags_simple.html.slim +11 -0
- data/app/views/wiki/_tags_form.html.slim +7 -0
- data/app/views/wiki/_tags_form_bottom.html.slim +5 -0
- data/app/views/wiki/_tags_show.html.slim +9 -0
- data/app/views/wiki/_tags_sidebar.html.slim +4 -0
- data/app/views/wiki/tag_index.html.slim +21 -0
- data/assets/javascripts/tags.js +19 -0
- data/assets/stylesheets/tags.css +119 -0
- data/config/locales/bg.yml +33 -0
- data/config/locales/cs.yml +33 -0
- data/config/locales/de.yml +33 -0
- data/config/locales/en.yml +33 -0
- data/config/locales/es.yml +33 -0
- data/config/locales/fr.yml +33 -0
- data/config/locales/it.yml +33 -0
- data/config/locales/ja.yml +33 -0
- data/config/locales/ko.yml +33 -0
- data/config/locales/pl.yml +33 -0
- data/config/locales/pt-BR.yml +33 -0
- data/config/locales/ru.yml +33 -0
- data/config/routes.rb +31 -0
- data/config/settings.yml +9 -0
- data/db/migrate/20201116145429_acts_as_taggable_migration.rb +40 -0
- data/db/migrate/20201123093214_migrate_existing_tags.rb +39 -0
- data/doc/images/additional-tags-framework.png +0 -0
- data/doc/images/additional-tags.gif +0 -0
- data/init.rb +31 -0
- data/lib/additional_tags.rb +107 -0
- data/lib/additional_tags/hooks.rb +63 -0
- data/lib/additional_tags/patches/agile_boards_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/agile_query_patch.rb +41 -0
- data/lib/additional_tags/patches/agile_versions_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/agile_versions_query_patch.rb +11 -0
- data/lib/additional_tags/patches/auto_completes_controller_patch.rb +42 -0
- data/lib/additional_tags/patches/calendars_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/dashboard_async_blocks_controller_patch.rb +11 -0
- data/lib/additional_tags/patches/dashboards_controller_patch.rb +11 -0
- data/lib/additional_tags/patches/gantts_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/imports_controller_patch.rb +12 -0
- data/lib/additional_tags/patches/issue_patch.rb +95 -0
- data/lib/additional_tags/patches/issue_query_patch.rb +55 -0
- data/lib/additional_tags/patches/issues_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/journal_patch.rb +18 -0
- data/lib/additional_tags/patches/my_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/queries_helper_patch.rb +40 -0
- data/lib/additional_tags/patches/reports_controller_patch.rb +32 -0
- data/lib/additional_tags/patches/settings_controller_patch.rb +12 -0
- data/lib/additional_tags/patches/time_entry_patch.rb +19 -0
- data/lib/additional_tags/patches/time_entry_query_patch.rb +53 -0
- data/lib/additional_tags/patches/time_report_patch.rb +46 -0
- data/lib/additional_tags/patches/timelog_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/wiki_controller_patch.rb +63 -0
- data/lib/additional_tags/patches/wiki_page_patch.rb +39 -0
- data/lib/additional_tags/tags.rb +134 -0
- data/lib/additional_tags/version.rb +3 -0
- metadata +177 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
lib = File.expand_path '../lib', __FILE__
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
require 'additional_tags/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'additional_tags'
|
|
7
|
+
spec.version = AdditionalTags::VERSION
|
|
8
|
+
spec.authors = ['AlphaNodes']
|
|
9
|
+
spec.email = ['alex@alphanodes.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Redmine plugin for adding tag functionality'
|
|
12
|
+
spec.description = 'Redmine plugin for adding tag functionality'
|
|
13
|
+
spec.homepage = 'https://github.com/alphanodes/additional_tags'
|
|
14
|
+
spec.license = 'GPL-2.0'
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
17
|
+
f.match(%r{^((test|spec|features)/|Gemfile)})
|
|
18
|
+
end
|
|
19
|
+
spec.bindir = 'exe'
|
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
|
+
spec.require_paths = ['lib']
|
|
22
|
+
spec.required_ruby_version = '>= 2.4'
|
|
23
|
+
|
|
24
|
+
spec.add_runtime_dependency 'acts-as-taggable-on', '~> 6.0'
|
|
25
|
+
|
|
26
|
+
spec.add_development_dependency 'bundler'
|
|
27
|
+
spec.add_development_dependency 'rake'
|
|
28
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
class AdditionalTagsController < ApplicationController
|
|
2
|
+
before_action :require_admin
|
|
3
|
+
before_action :find_tag, only: %i[edit update]
|
|
4
|
+
before_action :bulk_find_tags, only: %i[context_menu merge destroy]
|
|
5
|
+
before_action :set_tag_list_path
|
|
6
|
+
|
|
7
|
+
helper :additional_tags_issues
|
|
8
|
+
|
|
9
|
+
def edit; end
|
|
10
|
+
|
|
11
|
+
def destroy
|
|
12
|
+
@tags.each do |tag|
|
|
13
|
+
begin
|
|
14
|
+
tag.reload.destroy
|
|
15
|
+
rescue ::ActiveRecord::RecordNotFound
|
|
16
|
+
Rails.logger.warn "Tag #{tag} could not be deleted"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
redirect_back_or_default @tag_list_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def update
|
|
23
|
+
@tag.name = params[:tag][:name] if params[:tag]
|
|
24
|
+
if @tag.save
|
|
25
|
+
flash[:notice] = l :notice_successful_update
|
|
26
|
+
respond_to do |format|
|
|
27
|
+
format.html do
|
|
28
|
+
redirect_to @tag_list_path
|
|
29
|
+
end
|
|
30
|
+
format.xml
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
respond_to do |format|
|
|
34
|
+
format.html { render action: 'edit' }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def context_menu
|
|
40
|
+
@tag = @tags.first if @tags.size == 1
|
|
41
|
+
@back = back_url
|
|
42
|
+
render layout: false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def merge
|
|
46
|
+
return unless request.post? &&
|
|
47
|
+
params[:tag].present? &&
|
|
48
|
+
params[:tag][:name].present?
|
|
49
|
+
|
|
50
|
+
AdditionalTags::Tags.merge params[:tag][:name], @tags
|
|
51
|
+
redirect_to @tag_list_path
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def set_tag_list_path
|
|
57
|
+
@tag_list_path = plugin_settings_path id: 'additional_tags', tab: 'manage_tags'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def bulk_find_tags
|
|
61
|
+
@tags = ActsAsTaggableOn::Tag.joins("JOIN #{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.taggings_table}" \
|
|
62
|
+
" ON #{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.taggings_table}.tag_id =" \
|
|
63
|
+
" #{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.id ")
|
|
64
|
+
.select("#{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.id," \
|
|
65
|
+
"#{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.name," \
|
|
66
|
+
"#{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.taggings_count," \
|
|
67
|
+
" COUNT(DISTINCT #{ActsAsTaggableOn.taggings_table}.taggable_id) AS count")
|
|
68
|
+
.where(id: params[:id] ? [params[:id]] : params[:ids])
|
|
69
|
+
.group("#{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.id" \
|
|
70
|
+
", #{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.name" \
|
|
71
|
+
", #{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.taggings_count")
|
|
72
|
+
raise ActiveRecord::RecordNotFound if @tags.empty?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def find_tag
|
|
76
|
+
@tag = ActsAsTaggableOn::Tag.find params[:id]
|
|
77
|
+
rescue ActiveRecord::RecordNotFound
|
|
78
|
+
render_404
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class IssueTagsController < ApplicationController
|
|
2
|
+
before_action :find_issues, only: %i[edit update]
|
|
3
|
+
|
|
4
|
+
def edit
|
|
5
|
+
return unless AdditionalTags.setting?(:active_issue_tags) &&
|
|
6
|
+
User.current.allowed_to?(:edit_issue_tags, @projects.first)
|
|
7
|
+
|
|
8
|
+
@issue_ids = params[:ids]
|
|
9
|
+
@is_bulk_editing = @issue_ids.size > 1
|
|
10
|
+
@issue_tags = if @is_bulk_editing
|
|
11
|
+
issues = @issues.map(&:tag_list)
|
|
12
|
+
issues.flatten!
|
|
13
|
+
issues.uniq
|
|
14
|
+
else
|
|
15
|
+
@issues.first.tag_list
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
@issue_tags.sort!
|
|
19
|
+
@most_used_tags = Issue.available_tags.most_used 10
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def update
|
|
23
|
+
if AdditionalTags.setting?(:active_issue_tags) &&
|
|
24
|
+
User.current.allowed_to?(:edit_issue_tags, @projects.first)
|
|
25
|
+
tags = params[:issue] && params[:issue][:tag_list] ? params[:issue][:tag_list].reject(&:empty?) : []
|
|
26
|
+
|
|
27
|
+
unless User.current.allowed_to?(:create_issue_tags, @projects.first) || Issue.allowed_tags?(tags)
|
|
28
|
+
flash[:error] = t(:notice_failed_to_add_tags)
|
|
29
|
+
return
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Issue.transaction do
|
|
33
|
+
@issues.each do |issue|
|
|
34
|
+
issue.tag_list = tags
|
|
35
|
+
issue.save!
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
flash[:notice] = t(:notice_tags_added)
|
|
39
|
+
else
|
|
40
|
+
flash[:error] = t(:notice_failed_to_add_tags)
|
|
41
|
+
end
|
|
42
|
+
rescue StandardError => e
|
|
43
|
+
Rails.logger.warn "Failed to add tags: #{e.inspect}"
|
|
44
|
+
flash[:error] = t(:notice_failed_to_add_tags)
|
|
45
|
+
ensure
|
|
46
|
+
redirect_to_referer_or { render text: 'Tags updated.', layout: true }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
|
|
3
|
+
module AdditionalTagsHelper
|
|
4
|
+
include ActsAsTaggableOn::TagsHelper
|
|
5
|
+
|
|
6
|
+
def manageable_tags
|
|
7
|
+
AdditionalTags::Tags.sort_tag_list ActsAsTaggableOn::Tag.where({})
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def manageable_tag_columns
|
|
11
|
+
return @manageable_tag_columns if defined? @manageable_tag_columns
|
|
12
|
+
|
|
13
|
+
columns = {}
|
|
14
|
+
|
|
15
|
+
if AdditionalTags.setting?(:active_issue_tags)
|
|
16
|
+
columns[:issue] = { label: l(:label_issue_plural),
|
|
17
|
+
tag_controller: :issues,
|
|
18
|
+
counts: Issue.available_tags.map { |tag| [tag.id, tag.count] }.to_h }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if AdditionalTags.setting?(:active_wiki_tags)
|
|
22
|
+
columns[:wiki] = { label: l(:label_wiki),
|
|
23
|
+
counts: WikiPage.available_tags.map { |tag| [tag.id, tag.count] }.to_h }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
call_hook :helper_additional_manageable_tag_columns, columns: columns
|
|
27
|
+
|
|
28
|
+
@manageable_tag_columns = columns
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def manageable_tag_column_values(tag)
|
|
32
|
+
columns = []
|
|
33
|
+
manageable_tag_columns.each do |_column, column_values|
|
|
34
|
+
cnt = column_values[:counts][tag.id]
|
|
35
|
+
cnt = 0 if cnt.blank?
|
|
36
|
+
|
|
37
|
+
columns << if cnt.positive? && column_values[:tag_controller]
|
|
38
|
+
link_to cnt, tag_url(tag.name, tag_controller: column_values[:tag_controller])
|
|
39
|
+
else
|
|
40
|
+
cnt
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
columns
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def render_tags_list(tags, options = {})
|
|
47
|
+
return if tags.blank?
|
|
48
|
+
|
|
49
|
+
style = options.delete(:style)
|
|
50
|
+
tags = tags.all.to_a if tags.respond_to?(:all)
|
|
51
|
+
|
|
52
|
+
case "#{AdditionalTags.setting :tags_sort_by}:#{AdditionalTags.setting :tags_sort_order}"
|
|
53
|
+
when 'name:desc'
|
|
54
|
+
tags = AdditionalTags::Tags.sort_tag_list(tags).reverse
|
|
55
|
+
when 'count:asc'
|
|
56
|
+
tags.sort! { |a, b| a.count <=> b.count }
|
|
57
|
+
when 'count:desc'
|
|
58
|
+
tags.sort! { |a, b| b.count <=> a.count }
|
|
59
|
+
else
|
|
60
|
+
tags = AdditionalTags::Tags.sort_tag_list tags
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
case style
|
|
64
|
+
when :list
|
|
65
|
+
list_el = 'ul'
|
|
66
|
+
item_el = 'li'
|
|
67
|
+
when :simple_cloud, :cloud
|
|
68
|
+
list_el = 'div'
|
|
69
|
+
item_el = 'span'
|
|
70
|
+
else
|
|
71
|
+
raise 'Unknown list style'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
content = ''.html_safe
|
|
75
|
+
if style == :list && AdditionalTags.setting(:tags_sort_by) == 'name'
|
|
76
|
+
tags.group_by { |tag| tag.name.downcase.first }.each do |letter, grouped_tags|
|
|
77
|
+
content << content_tag(item_el, letter.upcase, class: 'letter')
|
|
78
|
+
add_tags style, grouped_tags, content, item_el, options
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
add_tags style, tags, content, item_el, options
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
content_tag(list_el, content, class: 'tags-cloud', style: (style == :simple_cloud ? 'text-align: left;' : ''))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def additional_tag_link(tag_object, options = {})
|
|
88
|
+
tag_name = []
|
|
89
|
+
tag_name << tag_object.name
|
|
90
|
+
|
|
91
|
+
options[:project] = @project if options[:project].blank? && @project.present?
|
|
92
|
+
|
|
93
|
+
use_colors = AdditionalTags.setting?(:use_colors)
|
|
94
|
+
if use_colors
|
|
95
|
+
tag_bg_color = additional_tag_color tag_object.name
|
|
96
|
+
tag_fg_color = additional_tag_fg_color tag_bg_color
|
|
97
|
+
tag_style = "background-color: #{tag_bg_color}; color: #{tag_fg_color}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
tag_name << tag.span("(#{tag_object.count})", class: 'tag-count') if options[:show_count]
|
|
101
|
+
|
|
102
|
+
content = if options[:link]
|
|
103
|
+
link_to safe_join(tag_name),
|
|
104
|
+
options[:link],
|
|
105
|
+
style: tag_style
|
|
106
|
+
elsif options[:link_wiki_tag]
|
|
107
|
+
link_to safe_join(tag_name),
|
|
108
|
+
project_wiki_index_path(options[:project], tag: tag_object.name),
|
|
109
|
+
style: tag_style
|
|
110
|
+
else
|
|
111
|
+
link_to safe_join(tag_name),
|
|
112
|
+
tag_url(tag_object.name, options),
|
|
113
|
+
style: tag_style
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
style = if use_colors
|
|
117
|
+
{ class: 'additional-tag-label-color', style: tag_style }
|
|
118
|
+
else
|
|
119
|
+
{ class: 'tag-label' }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
tag.span content, style
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def additional_tag_color(tag_name)
|
|
126
|
+
"##{Digest::MD5.hexdigest(tag_name)[0..5]}"
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def additional_tag_fg_color(bg_color)
|
|
130
|
+
# calculate contrast text color according to YIQ method
|
|
131
|
+
# https://24ways.org/2010/calculating-color-contrast/
|
|
132
|
+
# https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
|
133
|
+
r = bg_color[1..2].hex
|
|
134
|
+
g = bg_color[3..4].hex
|
|
135
|
+
b = bg_color[5..6].hex
|
|
136
|
+
(r * 299 + g * 587 + b * 114) >= 128_000 ? 'black' : 'white'
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# plain list of tags
|
|
140
|
+
def additional_plain_tag_list(tags, sep = ' ')
|
|
141
|
+
s = if tags.blank?
|
|
142
|
+
['']
|
|
143
|
+
else
|
|
144
|
+
tags.map(&:name)
|
|
145
|
+
end
|
|
146
|
+
s.join sep
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def additional_tag_links(tag_list, options = {})
|
|
150
|
+
return if tag_list.blank?
|
|
151
|
+
|
|
152
|
+
sep = if options[:use_colors].nil? || options[:use_colors]
|
|
153
|
+
' '
|
|
154
|
+
else
|
|
155
|
+
', '
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
unsorted = options.delete(:unsorted)
|
|
159
|
+
tag_list = AdditionalTags::Tags.sort_tag_list(tag_list) unless unsorted
|
|
160
|
+
|
|
161
|
+
safe_join tag_list.map { |tag| additional_tag_link tag, options }, sep
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
def tag_url(tag_name, options = {})
|
|
167
|
+
action = options[:tag_action].presence || (controller_name == 'hrm_user_resources' ? 'show' : 'index')
|
|
168
|
+
|
|
169
|
+
fields = [:tags]
|
|
170
|
+
values = { tags: [tag_name] }
|
|
171
|
+
operators = { tags: '=' }
|
|
172
|
+
|
|
173
|
+
if options[:filter].present?
|
|
174
|
+
field = options[:filter][:field]
|
|
175
|
+
fields << field
|
|
176
|
+
operators[field] = options[:filter][:operator]
|
|
177
|
+
values[field] = options[:filter][:value] if options[:filter].key?(:value)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
{ controller: options[:tag_controller].presence || controller_name,
|
|
181
|
+
action: action,
|
|
182
|
+
set_filter: 1,
|
|
183
|
+
project_id: options[:project],
|
|
184
|
+
f: fields,
|
|
185
|
+
v: values,
|
|
186
|
+
op: operators }
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def add_tags(style, tags, content, item_el, options)
|
|
190
|
+
tag_cloud tags, (1..8).to_a do |tag, weight|
|
|
191
|
+
content << ' '.html_safe + content_tag(item_el,
|
|
192
|
+
additional_tag_link(tag, options),
|
|
193
|
+
class: "tag-nube-#{weight}",
|
|
194
|
+
style: (style == :simple_cloud ? 'font-size: 1em;' : '')) + ' '.html_safe
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module AdditionalTagsIssuesHelper
|
|
2
|
+
# Hacked render_api_custom_values to add plugin values to issue api
|
|
3
|
+
def render_api_custom_values(custom_values, api)
|
|
4
|
+
rc = super
|
|
5
|
+
|
|
6
|
+
if @issue.present? &&
|
|
7
|
+
(defined?(controller_name) && controller_name == 'issues' && action_name == 'show' || !defined?(controller_name)) &&
|
|
8
|
+
User.current.allowed_to?(:view_issues, @project)
|
|
9
|
+
|
|
10
|
+
api.array :tags do
|
|
11
|
+
@issue.tags.each do |tag|
|
|
12
|
+
api.tag(id: tag.id, name: tag.name)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
rc
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def sidebar_tags
|
|
21
|
+
# we do not want tags on issue import
|
|
22
|
+
return if controller_name == 'imports'
|
|
23
|
+
|
|
24
|
+
unless @sidebar_tags
|
|
25
|
+
@sidebar_tags = []
|
|
26
|
+
if AdditionalTags.show_sidebar_tags?
|
|
27
|
+
@sidebar_tags = Issue.available_tags project: @project,
|
|
28
|
+
open_issues_only: AdditionalTags.setting?(:open_issues_only)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
@sidebar_tags.to_a
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def render_sidebar_tags
|
|
35
|
+
options = { show_count: AdditionalTags.setting?(:show_with_count),
|
|
36
|
+
filter: AdditionalTags.setting?(:open_issues_only) ? { field: :status_id, operator: 'o' } : nil,
|
|
37
|
+
style: AdditionalTags.setting(:tags_sidebar).to_sym,
|
|
38
|
+
project: @project }
|
|
39
|
+
|
|
40
|
+
options[:tag_action] = 'show' if %w[gantts calendars].include? controller_name
|
|
41
|
+
render_tags_list sidebar_tags, options
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module AdditionalTagsWikiHelper
|
|
2
|
+
def sidebar_tags
|
|
3
|
+
unless @sidebar_tags
|
|
4
|
+
@sidebar_tags = []
|
|
5
|
+
@sidebar_tags = WikiPage.available_tags(project: @project) if AdditionalTags.show_sidebar_tags?
|
|
6
|
+
end
|
|
7
|
+
@sidebar_tags
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def render_sidebar_tags
|
|
11
|
+
render_tags_list sidebar_tags,
|
|
12
|
+
show_count: AdditionalTags.setting?(:show_with_count),
|
|
13
|
+
style: AdditionalTags.setting(:tags_sidebar).to_sym,
|
|
14
|
+
link_wiki_tag: true,
|
|
15
|
+
project: @project
|
|
16
|
+
end
|
|
17
|
+
end
|