additional_tags 1.0.6 → 3.0.9
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 +4 -4
- data/README.md +26 -7
- data/app/controllers/additional_tags_controller.rb +9 -9
- data/app/controllers/issue_tags_controller.rb +6 -1
- data/app/helpers/additional_tags_helper.rb +41 -32
- data/app/helpers/additional_tags_issues_helper.rb +13 -5
- data/app/helpers/additional_tags_wiki_helper.rb +6 -5
- data/app/models/additional_tag.rb +98 -0
- data/app/views/additional_tags/_tag_list.html.slim +10 -4
- data/app/views/additional_tags/merge.html.slim +0 -1
- data/app/views/additional_tags/settings/_general.html.slim +7 -1
- data/app/views/additional_tags/settings/_manage_tags.html.slim +8 -1
- data/app/views/context_menus/_issues_tags.html.slim +7 -1
- data/app/views/dashboards/blocks/_issue_tags.html.slim +3 -1
- data/app/views/issue_tags/_edit_modal.html.slim +7 -7
- data/app/views/issues/_tags.html.slim +6 -1
- data/app/views/issues/_tags_bulk_edit.html.slim +2 -1
- data/app/views/wiki/_tags_form.html.slim +4 -0
- data/app/views/wiki/_tags_show.html.slim +1 -1
- data/assets/javascripts/tags.js +3 -3
- data/assets/stylesheets/tags.css +41 -16
- data/config/locales/bg.yml +17 -11
- data/config/locales/cs.yml +18 -12
- data/config/locales/de.yml +18 -12
- data/config/locales/en.yml +18 -12
- data/config/locales/es.yml +18 -12
- data/config/locales/fr.yml +18 -12
- data/config/locales/it.yml +18 -12
- data/config/locales/ja.yml +17 -11
- data/config/locales/ko.yml +17 -11
- data/config/locales/pl.yml +18 -12
- data/config/locales/pt-BR.yml +17 -11
- data/config/locales/ru.yml +33 -27
- data/config/settings.yml +5 -5
- data/lib/additional_tags/hooks/view_hook.rb +17 -5
- data/lib/additional_tags/patches/issue_patch.rb +54 -9
- data/lib/additional_tags/patches/issue_query_patch.rb +18 -0
- data/lib/additional_tags/patches/queries_helper_patch.rb +13 -3
- data/lib/additional_tags/patches/query_patch.rb +23 -2
- data/lib/additional_tags/patches/wiki_page_patch.rb +6 -1
- data/lib/additional_tags/plugin_version.rb +1 -1
- data/lib/additional_tags/tags.rb +35 -13
- data/lib/additional_tags.rb +5 -0
- metadata +5 -44
- data/.eslintrc.yml +0 -17
- data/.github/workflows/codeql-analysis.yml +0 -70
- data/.github/workflows/linters.yml +0 -43
- data/.github/workflows/tests.yml +0 -134
- data/.gitignore +0 -11
- data/.rubocop.yml +0 -133
- data/.slim-lint.yml +0 -27
- data/.stylelintrc.json +0 -163
- data/Rakefile +0 -13
- data/additional_tags.gemspec +0 -32
- data/doc/images/additional-tags-framework.png +0 -0
- data/doc/images/additional-tags.gif +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c412788c20ba3626ad2707dea2a34a96b9d2e0378c70b55bd5b8f116d92dc8cf
|
4
|
+
data.tar.gz: 6b2dd7625fe8b4e4249631bee75ad0e2a0f1be4a481382e1f346026683059246
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9293e12799c232dca72262bf3af55c84a23481e0fd1b0c6a38199f145ce3f7dca95ee218bb661f764eb49251de602abaefef41dc4da1463f4e97714097d0aa93
|
7
|
+
data.tar.gz: 57377f76241c07b63651ddece4ee6a14f983dd1faea0544b2d7ca5e3453a302142b19442252b6d71c1884c54fed4083eb84f818dc72e0b0f91927de39b381b8f
|
data/README.md
CHANGED
@@ -4,16 +4,35 @@
|
|
4
4
|
|
5
5
|
## Features
|
6
6
|
|
7
|
-
- Tags for issues
|
8
|
-
-
|
7
|
+
- Tags for issues. To use them you need to:
|
8
|
+
- *Activate issue tags* in the plugin configuration
|
9
|
+
- and update your role permissions in the Redmine administration *Roles & permissions / Issue tracking*.
|
10
|
+
- Tags for wiki pages. To use them you need to:
|
11
|
+
- *Activate wiki tags* in the plugin configuration
|
12
|
+
- and update your role permissions in the Redmine administration *Roles & permissions / Wiki*
|
13
|
+
- Available role permissions for issue tags (section *Issue tracking*):
|
14
|
+
- Add issue tags
|
15
|
+
- Edit issue tags
|
16
|
+
- Display issue tags
|
17
|
+
- Available role permissions wiki tags (section *Wiki*):
|
18
|
+
- Add wiki tags
|
19
|
+
- Managing tags centrally in the plugin settings (edit, delete, merge)-
|
20
|
+
- Grouped tags.
|
21
|
+
- Grouping of tags possible, when using a colon in tag (all tags with same base name get the same color). Typo example: ``Plugin:HRM``
|
22
|
+
- Scoped tags:
|
23
|
+
- Grouping of tags via *Scoped tags* possible, when using two colons in tag. Typo example: ``Product::Sprint 1``
|
24
|
+
- Only one tag of the same base name is allowed for an entity
|
25
|
+
- Base name and tag value are displayed seperatly
|
9
26
|
- Accented and non-latin characters supported for tag order
|
10
|
-
-
|
11
|
-
-
|
12
|
-
|
13
|
-
- Custom tags and tagging tables (additional_tags and additional_taggings). If a other plugin
|
14
|
-
used tags or tagging tables for issue or wiki tagging, there tags will be migrated automatically
|
27
|
+
- Color theme selection possible
|
28
|
+
- Custom tags and tagging tables (additional_tags and additional_taggings). If another plugin
|
29
|
+
used tags or tagging tables for issue or wiki tagging, tags will be migrated automatically there
|
15
30
|
- Based on the very popular [acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on)
|
16
31
|
|
32
|
+

|
33
|
+
|
34
|
+
The screenshot shows: regular tags, grouped tags and scoped tags. The colors are assigned randomly. But you can change the color by choosing a *Color theme* in the plugin settings.
|
35
|
+
|
17
36
|

|
18
37
|
|
19
38
|
Other plugins use additional_tags as framework in order to support tags for their entities.
|
@@ -33,15 +33,6 @@ class AdditionalTagsController < ApplicationController
|
|
33
33
|
|
34
34
|
def edit; end
|
35
35
|
|
36
|
-
def destroy
|
37
|
-
@tags.each do |tag|
|
38
|
-
tag.reload.destroy!
|
39
|
-
rescue ::ActiveRecord::RecordNotFound, ::ActiveRecord::RecordNotDestroyed
|
40
|
-
Rails.logger.warn "Tag #{tag} could not be deleted"
|
41
|
-
end
|
42
|
-
redirect_back_or_default @tag_list_path
|
43
|
-
end
|
44
|
-
|
45
36
|
def update
|
46
37
|
@tag.name = params[:tag][:name] if params[:tag]
|
47
38
|
if @tag.save
|
@@ -59,6 +50,15 @@ class AdditionalTagsController < ApplicationController
|
|
59
50
|
end
|
60
51
|
end
|
61
52
|
|
53
|
+
def destroy
|
54
|
+
@tags.each do |tag|
|
55
|
+
tag.reload.destroy!
|
56
|
+
rescue ::ActiveRecord::RecordNotFound, ::ActiveRecord::RecordNotDestroyed
|
57
|
+
Rails.logger.warn "Tag #{tag} could not be deleted"
|
58
|
+
end
|
59
|
+
redirect_back_or_default @tag_list_path
|
60
|
+
end
|
61
|
+
|
62
62
|
def context_menu
|
63
63
|
@tag = @tags.first if @tags.size == 1
|
64
64
|
@back = back_url
|
@@ -19,6 +19,7 @@ class IssueTagsController < ApplicationController
|
|
19
19
|
|
20
20
|
@issue_tags.sort!
|
21
21
|
@most_used_tags = Issue.available_tags.most_used 10
|
22
|
+
@append = params[:append] == 'true'
|
22
23
|
end
|
23
24
|
|
24
25
|
def update
|
@@ -33,7 +34,11 @@ class IssueTagsController < ApplicationController
|
|
33
34
|
|
34
35
|
Issue.transaction do
|
35
36
|
@issues.each do |issue|
|
36
|
-
issue.
|
37
|
+
issue.init_journal User.current
|
38
|
+
# add tags added in placeholder for a single/multiple issue or overwrite tags for single issue
|
39
|
+
params[:append] == 'true' ? issue.tag_list << tags : issue.tag_list = tags
|
40
|
+
|
41
|
+
issue.tags_to_journal issue.tag_list_was&.to_s, issue.tag_list.to_s
|
37
42
|
issue.save!
|
38
43
|
end
|
39
44
|
end
|
@@ -53,7 +53,7 @@ module AdditionalTagsHelper
|
|
53
53
|
when 'name:desc'
|
54
54
|
tags = AdditionalTags::Tags.sort_tag_list(tags).reverse
|
55
55
|
when 'count:asc'
|
56
|
-
tags.
|
56
|
+
tags.sort_by!(&:count)
|
57
57
|
when 'count:desc'
|
58
58
|
tags.sort! { |a, b| b.count <=> a.count }
|
59
59
|
else
|
@@ -66,7 +66,11 @@ module AdditionalTagsHelper
|
|
66
66
|
def render_tags_list(tags, **options)
|
67
67
|
return if tags.blank?
|
68
68
|
|
69
|
-
|
69
|
+
options[:show_count] = AdditionalTags.setting? :show_with_count unless options.key? :show_count
|
70
|
+
options[:color_theme] = AdditionalTags.setting :tags_color_theme unless options.key? :color_theme
|
71
|
+
options[:use_colors] = AdditionalTags.use_colors? unless options.key? :use_colors
|
72
|
+
|
73
|
+
style = options.key?(:style) ? options.delete(:style) : AdditionalTags.setting(:tags_sidebar).to_sym
|
70
74
|
tags = tags.all.to_a if tags.respond_to? :all
|
71
75
|
tags = sort_tags_for_list tags
|
72
76
|
|
@@ -94,22 +98,36 @@ module AdditionalTagsHelper
|
|
94
98
|
content_tag(list_el, content, class: 'tags-cloud', style: (style == :simple_cloud ? 'text-align: left;' : ''))
|
95
99
|
end
|
96
100
|
|
97
|
-
def additional_tag_link(tag_object,
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
def additional_tag_link(tag_object,
|
102
|
+
link: nil,
|
103
|
+
link_wiki_tag: false,
|
104
|
+
show_count: false,
|
105
|
+
use_colors: nil,
|
106
|
+
name: nil,
|
107
|
+
color_theme: nil,
|
108
|
+
**options)
|
105
109
|
options[:project] = @project if options[:project].blank? && @project.present?
|
106
|
-
|
110
|
+
if !options.key?(:display_type) && @query && @query.display_type != @query.default_display_type
|
111
|
+
options[:display_type] = @query.display_type
|
112
|
+
end
|
113
|
+
|
114
|
+
use_colors = AdditionalTags.use_colors? if use_colors.nil?
|
115
|
+
color_theme = AdditionalTags.setting :tags_color_theme if color_theme.nil?
|
116
|
+
|
117
|
+
tag_info = AdditionalTag.new name: name.nil? ? tag_object.name : name,
|
118
|
+
disable_grouping: !use_colors,
|
119
|
+
color_theme: color_theme
|
120
|
+
tag_name = [tag_info.tag_name]
|
121
|
+
|
122
|
+
tag_style = "background-color: #{tag_info.tag_bg_color}; color: #{tag_info.tag_fg_color}" if use_colors
|
107
123
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
124
|
+
if tag_info.scoped?
|
125
|
+
tag_name << if show_count
|
126
|
+
tag.span tag_info.group_value, class: 'tag-group-value'
|
127
|
+
else
|
128
|
+
tag.span tag_info.group_value, class: 'tag-group-value tag-group-nocount'
|
129
|
+
end
|
130
|
+
end
|
113
131
|
|
114
132
|
tag_name << tag.span(tag_object.count, class: 'tag-count') if show_count
|
115
133
|
|
@@ -139,20 +157,6 @@ module AdditionalTagsHelper
|
|
139
157
|
tag.span content, **style
|
140
158
|
end
|
141
159
|
|
142
|
-
def additional_tag_color(tag_name)
|
143
|
-
"##{Digest::SHA256.hexdigest(tag_name)[0..5]}"
|
144
|
-
end
|
145
|
-
|
146
|
-
def additional_tag_fg_color(bg_color)
|
147
|
-
# calculate contrast text color according to YIQ method
|
148
|
-
# https://24ways.org/2010/calculating-color-contrast/
|
149
|
-
# https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
150
|
-
r = bg_color[1..2].hex
|
151
|
-
g = bg_color[3..4].hex
|
152
|
-
b = bg_color[5..6].hex
|
153
|
-
(r * 299 + g * 587 + b * 114) >= 128_000 ? 'black' : 'white'
|
154
|
-
end
|
155
|
-
|
156
160
|
# plain list of tags
|
157
161
|
def additional_plain_tag_list(tags, sep: nil)
|
158
162
|
sep ||= "#{Query.additional_csv_separator} "
|
@@ -177,12 +181,16 @@ module AdditionalTagsHelper
|
|
177
181
|
unsorted = options.delete :unsorted
|
178
182
|
tag_list = AdditionalTags::Tags.sort_tag_list tag_list unless unsorted
|
179
183
|
|
184
|
+
# set defaults if not defined
|
185
|
+
options[:use_colors] = AdditionalTags.use_colors? unless options.key? :use_colors
|
186
|
+
options[:color_theme] = AdditionalTags.setting :tags_color_theme unless options.key? :color_theme
|
187
|
+
|
180
188
|
safe_join tag_list.map { |tag| additional_tag_link tag, **options },
|
181
189
|
additional_tag_sep(use_colors: options[:use_colors])
|
182
190
|
end
|
183
191
|
|
184
192
|
def link_to_issue_tags_totals(entries:, project:, open_issues_only:)
|
185
|
-
sum = if entries.blank? || entries.
|
193
|
+
sum = if entries.blank? || entries.empty?
|
186
194
|
0
|
187
195
|
else
|
188
196
|
query = IssueQuery.new project: project, name: '_'
|
@@ -208,7 +216,7 @@ module AdditionalTagsHelper
|
|
208
216
|
|
209
217
|
private
|
210
218
|
|
211
|
-
def tag_url(tag_name, filter: nil, tag_action: nil, tag_controller: nil, project: nil)
|
219
|
+
def tag_url(tag_name, filter: nil, tag_action: nil, tag_controller: nil, project: nil, display_type: nil)
|
212
220
|
action = tag_action.presence || (controller_name == 'hrm_user_resources' ? 'show' : 'index')
|
213
221
|
|
214
222
|
fields = [:tags]
|
@@ -225,6 +233,7 @@ module AdditionalTagsHelper
|
|
225
233
|
{ controller: tag_controller.presence || controller_name,
|
226
234
|
action: action,
|
227
235
|
set_filter: 1,
|
236
|
+
display_type: display_type,
|
228
237
|
project_id: project,
|
229
238
|
f: fields,
|
230
239
|
v: values,
|
@@ -10,8 +10,18 @@ module AdditionalTagsIssuesHelper
|
|
10
10
|
AdditionalTags.setting?(:active_issue_tags) && User.current.allowed_to?(:view_issue_tags, @project)
|
11
11
|
|
12
12
|
api.array :tags do
|
13
|
-
|
14
|
-
|
13
|
+
# support tags, which are not saved to database
|
14
|
+
if @issue.tag_list.present?
|
15
|
+
if @issue.tags.present? && @issue.tags.map(&:name) == @issue.tag_list
|
16
|
+
@issue.tags.each do |tag|
|
17
|
+
api.tag id: tag.id, name: tag.name
|
18
|
+
end
|
19
|
+
else
|
20
|
+
@issue.tag_list.each do |tag_name|
|
21
|
+
# there is no id for unsaved tags
|
22
|
+
api.tag name: tag_name
|
23
|
+
end
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
@@ -44,9 +54,7 @@ module AdditionalTagsIssuesHelper
|
|
44
54
|
end
|
45
55
|
|
46
56
|
def render_sidebar_tags
|
47
|
-
options = {
|
48
|
-
filter: AdditionalTags.setting?(:open_issues_only) ? { field: :status_id, operator: 'o' } : nil,
|
49
|
-
style: AdditionalTags.setting(:tags_sidebar).to_sym,
|
57
|
+
options = { filter: AdditionalTags.setting?(:open_issues_only) ? { field: :status_id, operator: 'o' } : nil,
|
50
58
|
project: @project }
|
51
59
|
|
52
60
|
options[:tag_action] = 'show' if %w[gantts calendars].include? controller_name
|
@@ -10,9 +10,7 @@ module AdditionalTagsWikiHelper
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def render_sidebar_tags
|
13
|
-
options = {
|
14
|
-
style: AdditionalTags.setting(:tags_sidebar).to_sym,
|
15
|
-
link_wiki_tag: true,
|
13
|
+
options = { link_wiki_tag: true,
|
16
14
|
project: @project }
|
17
15
|
|
18
16
|
render_tags_list sidebar_tags, **options
|
@@ -20,12 +18,15 @@ module AdditionalTagsWikiHelper
|
|
20
18
|
|
21
19
|
def render_wiki_index_title(project: nil, name: nil, tag: nil, title: :label_wiki)
|
22
20
|
if tag.present?
|
21
|
+
tag_object = ActsAsTaggableOn::Tag.new name: tag
|
22
|
+
|
23
23
|
if project
|
24
|
-
|
24
|
+
safe_join [l(:label_wiki_index_for_tag), additional_tag_link(tag_object, link: '#')], ' '
|
25
25
|
else
|
26
26
|
title = [link_to(l(title), wiki_index_path)]
|
27
27
|
title << Additionals::LIST_SEPARATOR
|
28
|
-
title <<
|
28
|
+
title << l(:label_wiki_index_for_tag)
|
29
|
+
title << additional_tag_link(tag_object, link: '#')
|
29
30
|
safe_join title, ' '
|
30
31
|
end
|
31
32
|
elsif name.present?
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AdditionalTag
|
4
|
+
GROUP_SEP = ':'
|
5
|
+
SCOPE_SEP = '::'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def valid_mutually_exclusive_tag(tag_list)
|
9
|
+
return true if tag_list.blank?
|
10
|
+
|
11
|
+
tags = tag_list.select { |t| t.include? SCOPE_SEP }
|
12
|
+
return true if tags.blank?
|
13
|
+
|
14
|
+
groups = tags.map { |t| new(name: t).group_name }
|
15
|
+
groups == groups.uniq
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# NOTE: only use bg_color parameter, if background color should not
|
20
|
+
# calculated by AdditionalTag - if you want to assign manual color
|
21
|
+
def initialize(name:, disable_grouping: false, color_theme: nil, bg_color: nil)
|
22
|
+
@tag_name = name.to_s
|
23
|
+
@disable_grouping = disable_grouping
|
24
|
+
@color_theme = color_theme.to_s
|
25
|
+
@bg_color = bg_color
|
26
|
+
end
|
27
|
+
|
28
|
+
def name_for_color
|
29
|
+
# different colors for non-grouped, grouped and scoped tag
|
30
|
+
name = if scoped? || grouped?
|
31
|
+
"#{group_name}#{sep}"
|
32
|
+
else
|
33
|
+
tag_name
|
34
|
+
end
|
35
|
+
|
36
|
+
if @color_theme.present? && @color_theme != '0' && @color_theme != '1'
|
37
|
+
"#{name}#{@color_theme}"
|
38
|
+
else
|
39
|
+
name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def tag_bg_color
|
44
|
+
@tag_bg_color ||= @bg_color || "##{Digest::SHA256.hexdigest(name_for_color)[0..5]}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# calculate contrast text color according to YIQ method
|
48
|
+
# https://24ways.org/2010/calculating-color-contrast/
|
49
|
+
# https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
50
|
+
def tag_fg_color
|
51
|
+
@tag_fg_color ||= begin
|
52
|
+
r = tag_bg_color[1..2].hex
|
53
|
+
g = tag_bg_color[3..4].hex
|
54
|
+
b = tag_bg_color[5..6].hex
|
55
|
+
(r * 299 + g * 587 + b * 114) >= 128_000 ? 'black' : 'white'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def sep
|
60
|
+
scoped? ? SCOPE_SEP : GROUP_SEP
|
61
|
+
end
|
62
|
+
|
63
|
+
def tag_name
|
64
|
+
scoped? ? group_name : @tag_name
|
65
|
+
end
|
66
|
+
|
67
|
+
def labels
|
68
|
+
@labels ||= scoped? ? scope_labels : group_labels
|
69
|
+
end
|
70
|
+
|
71
|
+
def scope_labels
|
72
|
+
@scope_labels ||= @tag_name.split(SCOPE_SEP).map(&:strip)
|
73
|
+
end
|
74
|
+
|
75
|
+
def group_labels
|
76
|
+
@group_labels ||= @tag_name.split(GROUP_SEP).map(&:strip)
|
77
|
+
end
|
78
|
+
|
79
|
+
def group_name
|
80
|
+
if labels.length > 2
|
81
|
+
labels[0...-1].join sep
|
82
|
+
else
|
83
|
+
labels.first
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def group_value
|
88
|
+
labels.last
|
89
|
+
end
|
90
|
+
|
91
|
+
def scoped?
|
92
|
+
!@disable_grouping && scope_labels.length > 1
|
93
|
+
end
|
94
|
+
|
95
|
+
def grouped?
|
96
|
+
!@disable_grouping && group_labels.length > 1
|
97
|
+
end
|
98
|
+
end
|
@@ -15,17 +15,23 @@
|
|
15
15
|
span.contextual
|
16
16
|
= link_to l(:label_edit_tags),
|
17
17
|
{},
|
18
|
-
onclick: "$('#
|
19
|
-
id: '
|
18
|
+
onclick: "$('#edit-tags-form').show(); $('#tags-data').hide(); return false;",
|
19
|
+
id: 'edit-tags-link'
|
20
20
|
|
21
|
-
#
|
21
|
+
#edit-tags-form.hidden
|
22
22
|
= form_tag update_url, method: :put do
|
23
23
|
= render defined?(tags_form) ? tags_form : 'tags_form',
|
24
24
|
css_id: defined?(css_id) ? css_id : nil
|
25
25
|
'
|
26
26
|
= submit_tag l(:button_save), class: 'button-small'
|
27
27
|
'
|
28
|
-
= link_to l(:button_cancel), {}, onclick: "$('#
|
28
|
+
= link_to l(:button_cancel), {}, onclick: "$('#edit-tags-form').hide(); $('#tags-data').show(); return false;"
|
29
|
+
|
30
|
+
javascript:
|
31
|
+
$(function() {
|
32
|
+
var eventSelect = $('#issue_tag_list');
|
33
|
+
eventSelect.on('select2:close', function(e) { fixScopedTags(e, eventSelect); });
|
34
|
+
})
|
29
35
|
|
30
36
|
- else
|
31
37
|
= additional_tag_links entry.tags,
|
@@ -23,7 +23,13 @@ fieldset.settings
|
|
23
23
|
options_for_select(%w[name last_created count].collect { |v| [l("tags_order_by_#{v}"), v] },
|
24
24
|
@settings['tags_suggestion_order'])
|
25
25
|
p
|
26
|
-
=
|
26
|
+
= additionals_settings_select :tags_color_theme, options_for_select([[l(:label_tags_without_color), '0'],
|
27
|
+
[l(:label_tag_color_theme, value: 1), '1'],
|
28
|
+
[l(:label_tag_color_theme, value: 2), 'a'],
|
29
|
+
[l(:label_tag_color_theme, value: 3), 'b'],
|
30
|
+
[l(:label_tag_color_theme, value: 4), 'c'],
|
31
|
+
[l(:label_tag_color_theme, value: 5), 'd']],
|
32
|
+
@settings['tags_color_theme'])
|
27
33
|
|
28
34
|
fieldset.settings
|
29
35
|
legend = l :label_issue_plural
|
@@ -13,11 +13,18 @@
|
|
13
13
|
th = column_values[:label]
|
14
14
|
th
|
15
15
|
tbody
|
16
|
+
- use_colors = AdditionalTags.use_colors?
|
17
|
+
- color_theme = AdditionalTags.setting :tags_color_theme
|
16
18
|
- tags.each do |tag|
|
17
19
|
tr.hascontextmenu id="#{tag.id}"
|
18
20
|
td.checkbox.hide-when-print
|
19
21
|
= check_box_tag 'ids[]', tag.id, false, id: nil
|
20
|
-
td
|
22
|
+
td
|
23
|
+
= additional_tag_link tag,
|
24
|
+
link: edit_additional_tag_path(tag),
|
25
|
+
use_colors: use_colors,
|
26
|
+
color_theme: color_theme
|
27
|
+
|
21
28
|
- manageable_tag_column_values(tag).each do |column|
|
22
29
|
td = column
|
23
30
|
td.buttons
|
@@ -5,6 +5,12 @@
|
|
5
5
|
ul
|
6
6
|
li
|
7
7
|
= context_menu_link l(:button_add),
|
8
|
-
edit_issue_tags_path(ids: @issue_ids, search: params[:search]),
|
8
|
+
edit_issue_tags_path(ids: @issue_ids, search: params[:search], append: 'true'),
|
9
9
|
remote: true,
|
10
10
|
class: 'icon icon-add'
|
11
|
+
- if @issue_ids.size == 1
|
12
|
+
li
|
13
|
+
= context_menu_link l(:button_edit),
|
14
|
+
edit_issue_tags_path(ids: @issue_ids, search: params[:search]),
|
15
|
+
remote: true,
|
16
|
+
class: 'icon icon-edit'
|
@@ -28,13 +28,15 @@ h3 = block_definition[:label]
|
|
28
28
|
th = l :label_closed_issues_plural
|
29
29
|
th = l :label_total
|
30
30
|
tbody
|
31
|
+
- color_theme = AdditionalTags.setting :tags_color_theme
|
31
32
|
- tags.each do |tag|
|
32
33
|
tr
|
33
34
|
td.name = additional_tag_link tag,
|
34
35
|
tag_action: 'index',
|
35
36
|
tag_controller: 'issues',
|
36
37
|
filter: issue_tag_status_filter(open_issues_only: open_issues_only),
|
37
|
-
use_colors: RedminePluginKit.true?(settings[:use_colors])
|
38
|
+
use_colors: RedminePluginKit.true?(settings[:use_colors]),
|
39
|
+
color_theme: color_theme
|
38
40
|
- unless open_issues_only
|
39
41
|
td.value = additional_tag_link tag,
|
40
42
|
tag_action: 'index',
|
@@ -1,4 +1,4 @@
|
|
1
|
-
h3.title = l :
|
1
|
+
h3.title = @append ? l(:label_add_tags) : l(:label_edit_tags)
|
2
2
|
|
3
3
|
- if @is_bulk_editing
|
4
4
|
h3 = l :label_bulk_edit_selected_issues
|
@@ -9,24 +9,24 @@ h3.title = l :label_add_tags
|
|
9
9
|
h3
|
10
10
|
span = link_to_issue @issues.first
|
11
11
|
|
12
|
-
= form_tag issue_tags_path(ids: @issue_ids, search: params[:search]) do
|
12
|
+
= form_tag issue_tags_path(ids: @issue_ids, search: params[:search], append: @append.to_s) do
|
13
13
|
fieldset.box
|
14
14
|
legend = l :field_tags
|
15
15
|
#issue_tags
|
16
16
|
= additionals_select2_tag 'issue[tag_list]',
|
17
|
-
options_for_select(@issue_tags.map { |tag| [tag, tag] }, @issue_tags),
|
17
|
+
options_for_select(@append ? {} : @issue_tags.map { |tag| [tag, tag] }, @issue_tags),
|
18
18
|
multiple: true,
|
19
19
|
style: 'width: 100%;',
|
20
20
|
url: issue_tags_auto_completes_path(project_id: @project),
|
21
21
|
placeholder: @is_bulk_editing ? t(:label_no_change_option) : '+ add tag',
|
22
22
|
tags: User.current.allowed_to?(:create_issue_tags, @project)
|
23
|
-
p.
|
24
|
-
= safe_join @most_used_tags.collect { |t| tag.span t.name, class: '
|
23
|
+
p.most-used-tags
|
24
|
+
= safe_join @most_used_tags.collect { |t| tag.span t.name, class: 'most-used-tag' }, ', '
|
25
25
|
|
26
26
|
.buttons
|
27
|
-
= submit_tag l(:button_add), name: nil
|
27
|
+
= submit_tag l(@append ? :button_add : :button_save), name: nil
|
28
28
|
'
|
29
|
-
= link_to_function l(:button_cancel), 'hideModal(this)
|
29
|
+
= link_to_function l(:button_cancel), 'hideModal(this)'
|
30
30
|
|
31
31
|
javascript:
|
32
32
|
var mostUsedTags = #{raw @most_used_tags.map(&:name)};
|
@@ -5,4 +5,9 @@
|
|
5
5
|
editable: issue.editable?(User.current),
|
6
6
|
css_id: 'issue_tag_list_show',
|
7
7
|
update_url: issue_path(issue),
|
8
|
-
use_colors: AdditionalTags.
|
8
|
+
use_colors: AdditionalTags.use_colors?
|
9
|
+
|
10
|
+
- if issue.editable? User.current
|
11
|
+
javascript:
|
12
|
+
var eventSelect = $('#issue_tag_list_show');
|
13
|
+
eventSelect.on('select2:close', function(e) { fixScopedTags(e, eventSelect); });
|
@@ -1,7 +1,8 @@
|
|
1
|
-
- tags =
|
1
|
+
- tags = Issue.common_tag_list_from_issues(@issues.map(&:id))
|
2
2
|
= additionals_select2_tag 'issue[tag_list]',
|
3
3
|
options_for_select(tags.map { |tag| [tag, tag] }, tags),
|
4
4
|
multiple: true,
|
5
5
|
url: issue_tags_auto_completes_path,
|
6
6
|
placeholder: l(:label_add_tags),
|
7
7
|
tags: true
|
8
|
+
= hidden_field_tag 'common_tags', tags.to_s
|
data/assets/javascripts/tags.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/* global mostUsedTags:writable */
|
2
2
|
$(function() {
|
3
|
-
$('body').on('click', '.
|
3
|
+
$('body').on('click', '.most-used-tags .most-used-tag', function(e) {
|
4
4
|
var $tagsSelect = $('select#issue_tag_list');
|
5
5
|
var tag = e.target.innerText;
|
6
6
|
if ($tagsSelect.find('option[value=\'' + tag + '\']').length === 0) {
|
@@ -10,10 +10,10 @@ $(function() {
|
|
10
10
|
|
11
11
|
mostUsedTags = $.grep(mostUsedTags, function(t) { return t != tag; });
|
12
12
|
var tagsHtml = mostUsedTags.map(function(tag) {
|
13
|
-
return '<span class="
|
13
|
+
return '<span class="most-used-tag">' + tag + '</span>';
|
14
14
|
}).join(', ');
|
15
15
|
|
16
|
-
var $mostUsedTagsContainer = $(e.target).parent('.
|
16
|
+
var $mostUsedTagsContainer = $(e.target).parent('.most-used-tags');
|
17
17
|
$mostUsedTagsContainer.empty();
|
18
18
|
$mostUsedTagsContainer.append(tagsHtml);
|
19
19
|
});
|