additional_tags 1.0.6 → 3.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -7
  3. data/app/controllers/additional_tags_controller.rb +9 -9
  4. data/app/controllers/issue_tags_controller.rb +6 -1
  5. data/app/helpers/additional_tags_helper.rb +41 -32
  6. data/app/helpers/additional_tags_issues_helper.rb +13 -5
  7. data/app/helpers/additional_tags_wiki_helper.rb +6 -5
  8. data/app/models/additional_tag.rb +98 -0
  9. data/app/views/additional_tags/_tag_list.html.slim +10 -4
  10. data/app/views/additional_tags/merge.html.slim +0 -1
  11. data/app/views/additional_tags/settings/_general.html.slim +7 -1
  12. data/app/views/additional_tags/settings/_manage_tags.html.slim +8 -1
  13. data/app/views/context_menus/_issues_tags.html.slim +7 -1
  14. data/app/views/dashboards/blocks/_issue_tags.html.slim +3 -1
  15. data/app/views/issue_tags/_edit_modal.html.slim +7 -7
  16. data/app/views/issues/_tags.html.slim +6 -1
  17. data/app/views/issues/_tags_bulk_edit.html.slim +2 -1
  18. data/app/views/wiki/_tags_form.html.slim +4 -0
  19. data/app/views/wiki/_tags_show.html.slim +1 -1
  20. data/assets/javascripts/tags.js +3 -3
  21. data/assets/stylesheets/tags.css +41 -16
  22. data/config/locales/bg.yml +17 -11
  23. data/config/locales/cs.yml +18 -12
  24. data/config/locales/de.yml +18 -12
  25. data/config/locales/en.yml +18 -12
  26. data/config/locales/es.yml +18 -12
  27. data/config/locales/fr.yml +18 -12
  28. data/config/locales/it.yml +18 -12
  29. data/config/locales/ja.yml +17 -11
  30. data/config/locales/ko.yml +17 -11
  31. data/config/locales/pl.yml +18 -12
  32. data/config/locales/pt-BR.yml +17 -11
  33. data/config/locales/ru.yml +33 -27
  34. data/config/settings.yml +5 -5
  35. data/lib/additional_tags/hooks/view_hook.rb +17 -5
  36. data/lib/additional_tags/patches/issue_patch.rb +54 -9
  37. data/lib/additional_tags/patches/issue_query_patch.rb +18 -0
  38. data/lib/additional_tags/patches/queries_helper_patch.rb +13 -3
  39. data/lib/additional_tags/patches/query_patch.rb +23 -2
  40. data/lib/additional_tags/patches/wiki_page_patch.rb +6 -1
  41. data/lib/additional_tags/plugin_version.rb +1 -1
  42. data/lib/additional_tags/tags.rb +35 -13
  43. data/lib/additional_tags.rb +5 -0
  44. metadata +5 -44
  45. data/.eslintrc.yml +0 -17
  46. data/.github/workflows/codeql-analysis.yml +0 -70
  47. data/.github/workflows/linters.yml +0 -43
  48. data/.github/workflows/tests.yml +0 -134
  49. data/.gitignore +0 -11
  50. data/.rubocop.yml +0 -133
  51. data/.slim-lint.yml +0 -27
  52. data/.stylelintrc.json +0 -163
  53. data/Rakefile +0 -13
  54. data/additional_tags.gemspec +0 -32
  55. data/doc/images/additional-tags-framework.png +0 -0
  56. data/doc/images/additional-tags.gif +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 05656ef90d3c7c796b1bd3d510f6a349fc77c8b1adbf43ca6135af8e48ca705e
4
- data.tar.gz: a22552cd9d096d6963dd9349c207da4755b1e3ba1d8dec560d404b3207ee1458
3
+ metadata.gz: c412788c20ba3626ad2707dea2a34a96b9d2e0378c70b55bd5b8f116d92dc8cf
4
+ data.tar.gz: 6b2dd7625fe8b4e4249631bee75ad0e2a0f1be4a481382e1f346026683059246
5
5
  SHA512:
6
- metadata.gz: 2eb18bdccf79be5d1f1b4327c11c3c838e434c8737edcfa096d62d61925170e53be4a6ae45fb486e0c5b3a008933dc30e3bd2c36de9db929fe1fb1e71225adf2
7
- data.tar.gz: 97fd974a51bcdf337c0246cd95c0313639d43aa73f19ac9a81f0f9efa87da0e3c02736970b5c8148566ded5bb3e670a2fb332a03f99d85f59caed219d12410be
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
- - Tags for wiki pages
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
- - View, edit and create tag permissions for issues
11
- - Create permission for wiki tags
12
- - Managing tags
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
+ ![screenshot](https://raw.githubusercontent.com/AlphaNodes/additional_tags/master/doc/images/tag-overview.png)
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
  ![screenshot](https://raw.githubusercontent.com/AlphaNodes/additional_tags/master/doc/images/additional-tags.gif)
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.tag_list = tags
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.sort! { |a, b| a.count <=> b.count }
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
- style = options.delete :style
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, link: nil, link_wiki_tag: false, show_count: false, use_colors: nil, name: nil, **options)
98
- tag_name = []
99
- tag_name << if name.nil?
100
- tag_object.name
101
- else
102
- name
103
- end
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
- use_colors = AdditionalTags.setting? :use_colors if use_colors.nil?
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
- tag_style = if use_colors
109
- tag_bg_color = additional_tag_color tag_object.name
110
- tag_fg_color = additional_tag_fg_color tag_bg_color
111
- "background-color: #{tag_bg_color}; color: #{tag_fg_color}"
112
- end
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.size.zero?
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
- @issue.tags.each do |tag|
14
- api.tag id: tag.id, name: tag.name
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 = { show_count: AdditionalTags.setting?(:show_with_count),
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 = { show_count: AdditionalTags.setting?(:show_with_count),
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
- t :label_wiki_index_for_tag_html, tag: tag
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 << t(:label_wiki_index_for_tag_html, tag: tag)
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: "$('#edit_tags_form').show(); $('#tags-data').hide(); return false;",
19
- id: 'edit_tags_link'
18
+ onclick: "$('#edit-tags-form').show(); $('#tags-data').hide(); return false;",
19
+ id: 'edit-tags-link'
20
20
 
21
- #edit_tags_form.hidden
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: "$('#edit_tags_form').hide(); $('#tags-data').show(); return false;"
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,
@@ -8,7 +8,6 @@ h2
8
8
  = error_messages_for 'tag'
9
9
  = additional_tag_links @tags,
10
10
  show_count: true,
11
- use_colors: AdditionalTags.setting?(:use_colors),
12
11
  link: '#'
13
12
  .box
14
13
  p
@@ -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
- = additionals_settings_checkbox :use_colors
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 = additional_tag_link tag, link: edit_additional_tag_path(tag)
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 :label_add_tags
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.most_used_tags
24
- = safe_join @most_used_tags.collect { |t| tag.span t.name, class: 'most_used_tag' }, ', '
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.setting?(:use_colors)
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 = defined?(form) ? form.object.tag_list : []
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
@@ -5,3 +5,7 @@
5
5
  url: wiki_tags_auto_completes_path(project_id: @project),
6
6
  placeholder: l(:label_add_tags),
7
7
  tags: true
8
+
9
+ javascript:
10
+ var eventSelect = $('#wiki_page_tag_list');
11
+ eventSelect.on('select2:close', function(e) { fixScopedTags(e, eventSelect); });
@@ -6,4 +6,4 @@
6
6
  link_wiki_tag: true,
7
7
  editable: User.current.allowed_to?(:add_wiki_tags, @project),
8
8
  update_url: update_tags_project_wiki_page_path(@project, page.title),
9
- use_colors: AdditionalTags.setting?(:use_colors)
9
+ use_colors: AdditionalTags.use_colors?
@@ -1,6 +1,6 @@
1
1
  /* global mostUsedTags:writable */
2
2
  $(function() {
3
- $('body').on('click', '.most_used_tags .most_used_tag', function(e) {
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="most_used_tag">' + tag + '</span>';
13
+ return '<span class="most-used-tag">' + tag + '</span>';
14
14
  }).join(', ');
15
15
 
16
- var $mostUsedTagsContainer = $(e.target).parent('.most_used_tags');
16
+ var $mostUsedTagsContainer = $(e.target).parent('.most-used-tags');
17
17
  $mostUsedTagsContainer.empty();
18
18
  $mostUsedTagsContainer.append(tagsHtml);
19
19
  });