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.
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
  });