additional_tags 1.0.2 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codeql-analysis.yml +70 -0
  3. data/.github/workflows/linters.yml +6 -2
  4. data/.github/workflows/tests.yml +8 -6
  5. data/.gitignore +2 -1
  6. data/.rubocop.yml +31 -6
  7. data/README.md +17 -18
  8. data/additional_tags.gemspec +6 -4
  9. data/app/controllers/additional_tags_controller.rb +23 -0
  10. data/app/helpers/additional_tags_helper.rb +60 -19
  11. data/app/helpers/additional_tags_issues_helper.rb +12 -2
  12. data/app/helpers/additional_tags_wiki_helper.rb +1 -25
  13. data/app/jobs/additional_tags_remove_unused_tag_job.rb +5 -0
  14. data/app/views/additional_tags/_body_bottom.html.slim +19 -0
  15. data/app/views/additional_tags/_html_head.html.slim +1 -4
  16. data/app/views/additional_tags/_tag_list.html.slim +1 -1
  17. data/app/views/additional_tags/context_menu.html.slim +1 -4
  18. data/app/views/additional_tags/index.api.rsb +5 -0
  19. data/app/views/additional_tags/settings/_manage_tags.html.slim +23 -23
  20. data/app/views/common/_tag_summary_block.html.slim +11 -0
  21. data/app/views/context_menus/_issues_tags.html.slim +1 -1
  22. data/app/views/dashboards/blocks/_issue_tags.html.slim +58 -0
  23. data/app/views/dashboards/blocks/_issue_tags_settings.html.slim +20 -0
  24. data/app/views/issue_tags/_edit_modal.html.slim +4 -2
  25. data/app/views/issues/_tags_sidebar.html.slim +4 -1
  26. data/assets/javascripts/tags.js +4 -3
  27. data/assets/stylesheets/tags.css +27 -13
  28. data/config/initializers/zeitwerk.rb +4 -0
  29. data/config/locales/bg.yml +5 -0
  30. data/config/locales/cs.yml +5 -0
  31. data/config/locales/de.yml +5 -0
  32. data/config/locales/en.yml +5 -0
  33. data/config/locales/es.yml +5 -0
  34. data/config/locales/fr.yml +5 -0
  35. data/config/locales/it.yml +5 -0
  36. data/config/locales/ja.yml +5 -0
  37. data/config/locales/ko.yml +5 -0
  38. data/config/locales/pl.yml +5 -0
  39. data/config/locales/pt-BR.yml +5 -0
  40. data/config/locales/ru.yml +28 -23
  41. data/config/routes.rb +1 -1
  42. data/db/migrate/20201123093214_migrate_existing_tags.rb +1 -1
  43. data/init.rb +9 -7
  44. data/lib/additional_tags/hooks/model_hook.rb +11 -0
  45. data/lib/additional_tags/hooks/view_hook.rb +79 -0
  46. data/lib/additional_tags/patches/auto_completes_controller_patch.rb +5 -6
  47. data/lib/additional_tags/patches/dashboard_content_patch.rb +28 -0
  48. data/lib/additional_tags/patches/issue_patch.rb +25 -28
  49. data/lib/additional_tags/patches/query_patch.rb +10 -3
  50. data/lib/additional_tags/patches/wiki_controller_patch.rb +1 -1
  51. data/lib/additional_tags/patches/wiki_page_patch.rb +50 -1
  52. data/lib/additional_tags/plugin_version.rb +7 -0
  53. data/lib/additional_tags/tags.rb +54 -4
  54. data/lib/additional_tags.rb +51 -65
  55. data/lib/tasks/additional_tags.rake +18 -0
  56. metadata +34 -12
  57. data/.github/workflows/brakeman.yml +0 -34
  58. data/app/views/reports/_tags_simple.html.slim +0 -11
  59. data/lib/additional_tags/hooks.rb +0 -75
  60. data/lib/additional_tags/patches/reports_controller_patch.rb +0 -34
  61. data/lib/additional_tags/version.rb +0 -5
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AdditionalTags
4
+ module Patches
5
+ module DashboardContentPatch
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ prepend InstanceOverwriteMethods
10
+ end
11
+
12
+ module InstanceOverwriteMethods
13
+ def block_definitions
14
+ blocks = super
15
+
16
+ blocks['issue_tags'] = {
17
+ label: l(:field_issue_tags),
18
+ permission: :view_issue_tags,
19
+ if: proc { AdditionalTags.setting?(:active_issue_tags) },
20
+ async: { partial: 'dashboards/blocks/issue_tags' }
21
+ }
22
+
23
+ blocks
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -6,12 +6,16 @@ module AdditionalTags
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
+ include Additionals::EntityMethodsGlobal
9
10
  include InstanceMethods
10
11
  acts_as_ordered_taggable
11
12
 
12
13
  before_save :prepare_save_tag_change
13
14
  before_save :sort_tag_list
14
15
 
16
+ after_commit :add_remove_unused_tags_job, on: %i[update destroy],
17
+ if: proc { AdditionalTags.setting?(:active_issue_tags) }
18
+
15
19
  alias_method :safe_attributes_without_tags=, :safe_attributes=
16
20
  alias_method :safe_attributes=, :safe_attributes_with_tags=
17
21
 
@@ -25,8 +29,11 @@ module AdditionalTags
25
29
  tags.all? { |tag| allowed_tags.include? tag }
26
30
  end
27
31
 
28
- def by_tags(project, with_subprojects: false)
29
- count_and_group_by project: project, association: :tags, with_subprojects: with_subprojects
32
+ def group_by_status_with_tags(project = nil)
33
+ visible(User.current, project: project).joins(:status)
34
+ .joins(:tags)
35
+ .group(:is_closed, 'tag_id')
36
+ .count
30
37
  end
31
38
 
32
39
  def available_tags(**options)
@@ -37,10 +44,6 @@ module AdditionalTags
37
44
  tags.joins("JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{table_name}.status_id")
38
45
  .where(issue_statuses: { is_closed: false })
39
46
  end
40
-
41
- def remove_unused_tags!
42
- AdditionalTagsRemoveUnusedTagJob.perform_later
43
- end
44
47
  end
45
48
 
46
49
  module InstanceMethods
@@ -53,36 +56,30 @@ module AdditionalTags
53
56
  end
54
57
 
55
58
  def safe_attributes_with_tags=(attrs, user = User.current)
56
- if attrs && attrs[:tag_list]
57
- tags = attrs.delete :tag_list
58
- tags = Array(tags).reject(&:empty?)
59
-
60
- if user.allowed_to?(:create_issue_tags, project) ||
61
- user.allowed_to?(:edit_issue_tags, project) && Issue.allowed_tags?(tags)
62
- attrs[:tag_list] = tags
63
- self.tag_list = tags
64
- end
65
- end
59
+ send :safe_attributes_without_tags=, attrs, user # required to fire first to get loaded project
60
+ return unless attrs && attrs[:tag_list]
61
+
62
+ tags = attrs.delete :tag_list
63
+ tags = Array(tags).reject(&:empty?)
64
+
65
+ Additionals.debug "tags: #{tags.inspect} - project: #{project&.id} - access: #{user.allowed_to? :create_issue_tags, project}"
66
66
 
67
- send 'safe_attributes_without_tags=', attrs, user
67
+ if user.allowed_to?(:create_issue_tags, project) ||
68
+ user.allowed_to?(:edit_issue_tags, project) && Issue.allowed_tags?(tags)
69
+ attrs[:tag_list] = tags # required fix for journal details
70
+ self.tag_list = tags # required fix for tags
71
+ end
68
72
  end
69
73
 
70
- def copy_from_with_tags(arg, **options)
71
- copy_from_without_tags(arg, **options)
74
+ def copy_from_with_tags(arg, options = nil)
75
+ options ||= {} # works with Ruby 3
76
+
77
+ copy_from_without_tags arg, **options
72
78
  issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg)
73
79
  self.tag_list = issue.tag_list
74
80
  self
75
81
  end
76
82
 
77
- def tags_to_journal(old_tags, new_tags)
78
- return if current_journal.blank? || old_tags == new_tags
79
-
80
- current_journal.details << JournalDetail.new(property: 'attr',
81
- prop_key: 'tag_list',
82
- old_value: old_tags,
83
- value: new_tags)
84
- end
85
-
86
83
  private
87
84
 
88
85
  def sort_tag_list
@@ -35,14 +35,16 @@ module AdditionalTags
35
35
  .map { |name| [name, name] }
36
36
  end
37
37
 
38
- def build_subquery_for_tags_field(klass:, operator:, values:, joined_table:, joined_field:, target_field: 'issue_id')
38
+ def build_subquery_for_tags_field(klass:, operator:, values:, joined_table:, joined_field:,
39
+ source_field: 'id', target_field: 'issue_id')
39
40
  quoted_joined_table = self.class.connection.quote_table_name joined_table
40
41
  quoted_joined_field = self.class.connection.quote_column_name joined_field
42
+ quoted_source_field = self.class.connection.quote_column_name source_field
41
43
  quoted_target_field = self.class.connection.quote_column_name target_field
42
44
  subsql = ActsAsTaggableOn::Tagging.joins("INNER JOIN #{quoted_joined_table}" \
43
45
  " ON additional_taggings.taggable_id = #{quoted_joined_table}.#{quoted_target_field}")
44
46
  .where(taggable_type: klass.name)
45
- .where("#{self.class.connection.quote_table_name queried_table_name}.id ="\
47
+ .where("#{self.class.connection.quote_table_name queried_table_name}.#{quoted_source_field} ="\
46
48
  " #{quoted_joined_table}.#{quoted_joined_field}")
47
49
  .select(1)
48
50
 
@@ -63,7 +65,12 @@ module AdditionalTags
63
65
  case operator
64
66
  when '=', '!'
65
67
  ids_list = klass.tagged_with(values, any: true).pluck :id
66
- "(#{klass.table_name}.id #{compare} (#{ids_list.join ','}))" if ids_list.present?
68
+ if ids_list.present?
69
+ "(#{klass.table_name}.id #{compare} (#{ids_list.join ','}))"
70
+ elsif values.present? && operator == '='
71
+ # special case: filter with deleted tag
72
+ '(1=0)'
73
+ end
67
74
  else
68
75
  entries = ActsAsTaggableOn::Tagging.where taggable_type: klass.name
69
76
  id_table = klass.table_name
@@ -31,7 +31,7 @@ module AdditionalTags
31
31
  @tag = params[:tag]
32
32
  return super unless AdditionalTags.setting?(:active_wiki_tags) && @tag.present?
33
33
 
34
- @pages = wiki_pages_with_tag @tag, @project
34
+ @pages = WikiPage.with_tags @tag, project: @project
35
35
 
36
36
  respond_to do |format|
37
37
  format.html do
@@ -27,6 +27,55 @@ module AdditionalTags
27
27
  options[:permission] = :view_wiki_pages
28
28
  AdditionalTags::Tags.available_tags self, **options
29
29
  end
30
+
31
+ def with_tags_scope(project: nil, wiki: nil)
32
+ scope = if wiki
33
+ wiki.pages
34
+ else
35
+ scope = WikiPage.joins wiki: :project
36
+ scope = scope.where wikis: { project_id: project.id } if project
37
+ scope
38
+ end
39
+
40
+ scope = scope.visible User.current, project: project if scope.respond_to? :visible
41
+ scope
42
+ end
43
+
44
+ def with_tags(tag, project: nil, order: 'title_asc', max_entries: nil)
45
+ wiki = project&.wiki
46
+
47
+ scope = with_tags_scope wiki: wiki, project: project
48
+ scope = scope.limit max_entries if max_entries
49
+
50
+ tags = Array tag
51
+ tags.map!(&:strip)
52
+ tags.compact_blank!
53
+ return [] if tags.count.zero?
54
+
55
+ tags.map!(&:downcase)
56
+
57
+ scope = scope.where(id: tagged_with(tags, any: true).ids)
58
+ .with_updated_on
59
+
60
+ return scope if order.nil?
61
+
62
+ sorted = order.split '_'
63
+ raise 'unsupported sort order' if sorted != 2 && %w[title date].exclude?(sorted.first)
64
+
65
+ order_dir = sorted.second == 'desc' ? 'DESC' : 'ASC'
66
+
67
+ case sorted.first
68
+ when 'date'
69
+ scope.joins(:content)
70
+ .reorder("#{WikiContent.table_name}.updated_on #{order_dir}")
71
+ else
72
+ if wiki.nil?
73
+ scope.order "#{Project.table_name}.name, #{WikiPage.table_name}.title #{order_dir}"
74
+ else
75
+ scope.includes(:parent).order "#{WikiPage.table_name}.title #{order_dir}"
76
+ end
77
+ end
78
+ end
30
79
  end
31
80
 
32
81
  module InstanceMethods
@@ -46,7 +95,7 @@ module AdditionalTags
46
95
  end
47
96
  end
48
97
 
49
- send 'safe_attributes_without_tags=', attrs, user
98
+ send :safe_attributes_without_tags=, attrs, user
50
99
  end
51
100
 
52
101
  private
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AdditionalTags
4
+ module PluginVersion
5
+ VERSION = '1.0.5' unless defined? VERSION
6
+ end
7
+ end
@@ -25,7 +25,7 @@ module AdditionalTags
25
25
 
26
26
  columns << "MIN(#{TAGGING_TABLE_NAME}.created_at) AS last_created" if options[:sort_by] == 'last_created'
27
27
 
28
- scope.select(columns.join(', '))
28
+ scope.select(columns.to_list)
29
29
  .joins(tag_for_joins(klass, **options.slice(:project_join, :project, :without_projects)))
30
30
  .group("#{TAG_TABLE_NAME}.id, #{TAG_TABLE_NAME}.name, #{TAG_TABLE_NAME}.taggings_count").having('COUNT(*) > 0')
31
31
  .order(build_order_sql(options[:sort_by], options[:order]))
@@ -35,7 +35,7 @@ module AdditionalTags
35
35
  ActsAsTaggableOn::Tag.all
36
36
  .joins(tag_for_joins(klass, without_projects: without_projects))
37
37
  .distinct
38
- .order("#{TAG_TABLE_NAME}.name")
38
+ .order(:name)
39
39
  end
40
40
 
41
41
  def tag_to_joins(klass)
@@ -49,7 +49,8 @@ module AdditionalTags
49
49
  end
50
50
 
51
51
  def remove_unused_tags
52
- ActsAsTaggableOn::Tag.where.not(id: ActsAsTaggableOn::Tagging.select(:tag_id).distinct)
52
+ ActsAsTaggableOn::Tag.left_outer_joins(:taggings)
53
+ .where(taggings: { id: nil })
53
54
  .each(&:destroy)
54
55
  end
55
56
 
@@ -64,7 +65,8 @@ module AdditionalTags
64
65
  tags_to_merge.reject { |t| t.id == tag.id }.each(&:destroy)
65
66
  # remove duplicate taggings
66
67
  dup_scope = ActsAsTaggableOn::Tagging.where tag_id: tag.id
67
- valid_ids = dup_scope.group(:tag_id, :taggable_id, :taggable_type, :tagger_id, :tagger_type, :context).pluck(Arel.sql('MIN(id)'))
68
+ valid_ids = dup_scope.group(:tag_id, :taggable_id, :taggable_type, :tagger_id, :tagger_type, :context)
69
+ .pluck(Arel.sql('MIN(id)'))
68
70
  dup_scope.where.not(id: valid_ids).destroy_all if valid_ids.any?
69
71
  # recalc count for new tag
70
72
  ActsAsTaggableOn::Tag.reset_counters tag.id, :taggings
@@ -86,6 +88,7 @@ module AdditionalTags
86
88
  end
87
89
 
88
90
  def build_relation_tags(entries)
91
+ entries = Array entries
89
92
  return [] if entries.none?
90
93
 
91
94
  tags = entries.map(&:tags)
@@ -94,8 +97,55 @@ module AdditionalTags
94
97
  tags.uniq
95
98
  end
96
99
 
100
+ def entity_group_by(scope:, tags:, statuses: nil, sub_groups: nil, group_id_is_bool: false)
101
+ counts = {}
102
+ tags.each do |tag|
103
+ values = { tag: tag, total: 0, total_sub_groups: 0, groups: [] }
104
+
105
+ if statuses
106
+ statuses.each do |status|
107
+ group_id = status.first
108
+ group = status.second
109
+ values[group] = status_for_tag_value scope: scope,
110
+ tag_id: tag.id,
111
+ group_id: group_id,
112
+ group_id_is_bool: group_id_is_bool
113
+ values[:groups] << { id: group_id, group: group, count: values[group] }
114
+ values[:total] += values[group]
115
+ values[:total_sub_groups] += values[group] if sub_groups&.include? group_id
116
+ end
117
+ else
118
+ values[:total] += status_for_tag_value scope: scope, tag_id: tag.id
119
+ end
120
+
121
+ values[:total_without_sub_groups] = values[:total] - values[:total_sub_groups]
122
+
123
+ counts[tag.name] = values
124
+ end
125
+
126
+ counts
127
+ end
128
+
97
129
  private
98
130
 
131
+ def status_for_tag_value(scope:, tag_id:, group_id: nil, group_id_is_bool: false)
132
+ value = if group_id_is_bool || group_id
133
+ if group_id_is_bool
134
+ if group_id
135
+ scope[[1, tag_id]] || scope[[true, tag_id]]
136
+ else
137
+ scope[[0, tag_id]] || scope[[false, tag_id]]
138
+ end
139
+ else
140
+ scope[[group_id, tag_id]]
141
+ end
142
+ else
143
+ scope[tag_id]
144
+ end
145
+
146
+ value || 0
147
+ end
148
+
99
149
  def build_order_sql(sort_by, order)
100
150
  order = order.present? && order == 'DESC' ? 'DESC' : 'ASC'
101
151
 
@@ -1,94 +1,80 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'additional_tags/version'
4
- require 'additional_tags/tags'
3
+ require 'redmine_plugin_kit'
4
+ require 'acts-as-taggable-on'
5
5
 
6
6
  module AdditionalTags
7
7
  TAG_TABLE_NAME = 'additional_tags'
8
8
  TAGGING_TABLE_NAME = 'additional_taggings'
9
9
 
10
+ include RedminePluginKit::PluginBase
11
+
10
12
  class << self
13
+ def show_sidebar_tags?
14
+ setting(:tags_sidebar).present? && setting(:tags_sidebar) != 'none'
15
+ end
16
+
17
+ private
18
+
11
19
  def setup
12
20
  raise 'Please install additionals plugin (https://github.com/alphanodes/additionals)' unless Redmine::Plugin.installed? 'additionals'
13
21
 
14
- Additionals.incompatible_plugins(%w[redmine_tags
15
- redmine_tagging
16
- redmineup_tags], 'additional_tags')
22
+ loader.incompatible? %w[redmine_tags
23
+ redmine_tagging
24
+ redmineup_tags]
17
25
 
18
26
  # Patches
19
- AutoCompletesController.include AdditionalTags::Patches::AutoCompletesControllerPatch
20
- CalendarsController.include AdditionalTags::Patches::CalendarsControllerPatch
21
- DashboardsController.include AdditionalTags::Patches::DashboardsControllerPatch
22
- DashboardAsyncBlocksController.include AdditionalTags::Patches::DashboardAsyncBlocksControllerPatch
23
- GanttsController.include AdditionalTags::Patches::GanttsControllerPatch
24
- MyController.include AdditionalTags::Patches::MyControllerPatch
25
- Issue.include AdditionalTags::Patches::IssuePatch
26
- Journal.include AdditionalTags::Patches::JournalPatch
27
- Query.include AdditionalTags::Patches::QueryPatch
28
- IssuesController.include AdditionalTags::Patches::IssuesControllerPatch
29
- ImportsController.include AdditionalTags::Patches::ImportsControllerPatch
30
- QueriesHelper.include AdditionalTags::Patches::QueriesHelperPatch
31
- ReportsController.include AdditionalTags::Patches::ReportsControllerPatch
32
- SettingsController.include AdditionalTags::Patches::SettingsControllerPatch
33
- Redmine::Helpers::TimeReport.include AdditionalTags::Patches::TimeReportPatch
34
- TimeEntry.include AdditionalTags::Patches::TimeEntryPatch
35
- TimelogController.include AdditionalTags::Patches::TimelogControllerPatch
36
- WikiController.include AdditionalTags::Patches::WikiControllerPatch
37
- WikiPage.include AdditionalTags::Patches::WikiPagePatch
38
-
39
- # because of this bug: https://www.redmine.org/issues/33290
40
- if Additionals.redmine_database_ready? TAG_TABLE_NAME
41
- IssueQuery.include AdditionalTags::Patches::IssueQueryPatch
42
- TimeEntryQuery.include AdditionalTags::Patches::TimeEntryQueryPatch
43
-
44
- if Redmine::Plugin.installed? 'redmine_agile'
45
- AgileQuery.include AdditionalTags::Patches::AgileQueryPatch
46
- AgileBoardsController.include AdditionalTags::Patches::AgileBoardsControllerPatch
47
- if AGILE_VERSION_TYPE == 'PRO version'
48
- AgileVersionsController.include AdditionalTags::Patches::AgileVersionsControllerPatch
49
- AgileVersionsQuery.include AdditionalTags::Patches::AgileVersionsQueryPatch
50
- end
51
- end
27
+ loader.add_patch %w[AutoCompletesController
28
+ CalendarsController
29
+ DashboardsController
30
+ DashboardAsyncBlocksController
31
+ GanttsController
32
+ MyController
33
+ Issue
34
+ DashboardContent
35
+ Journal
36
+ Query
37
+ IssuesController
38
+ ImportsController
39
+ QueriesHelper
40
+ SettingsController
41
+ TimeEntry
42
+ TimelogController
43
+ WikiController
44
+ WikiPage]
45
+
46
+ loader.add_patch({ target: Redmine::Helpers::TimeReport,
47
+ patch: 'TimeReport' })
48
+
49
+ loader.add_patch %w[IssueQuery TimeEntryQuery]
50
+
51
+ if Redmine::Plugin.installed? 'redmine_agile'
52
+ loader.add_patch %w[AgileQuery AgileBoardsController]
53
+ loader.add_patch %w[AgileVersionsController AgileVersionsQuery] if AGILE_VERSION_TYPE == 'PRO version'
52
54
  end
53
55
 
54
- # Hooks
55
- require_dependency 'additional_tags/hooks'
56
- end
57
-
58
- # support with default setting as fall back
59
- def setting(value)
60
- if settings.key? value
61
- settings[value]
62
- else
63
- Additionals.load_settings('additional_tags')[value]
64
- end
65
- end
66
-
67
- def setting?(value)
68
- Additionals.true? settings[value]
69
- end
70
-
71
- def show_sidebar_tags?
72
- setting(:tags_sidebar).present? && setting(:tags_sidebar) != 'none'
73
- end
74
-
75
- private
56
+ # Apply patches and helper
57
+ loader.apply!
76
58
 
77
- def settings
78
- Setting[:plugin_additional_tags]
59
+ # Load view hooks
60
+ loader.load_view_hooks!
79
61
  end
80
62
  end
81
63
 
82
64
  # Run the classic redmine plugin initializer after rails boot
83
65
  class Plugin < ::Rails::Engine
84
- require 'acts-as-taggable-on'
66
+ require 'additional_tags/tags'
85
67
 
86
68
  ActsAsTaggableOn.tags_table = TAG_TABLE_NAME
87
69
  ActsAsTaggableOn.taggings_table = TAGGING_TABLE_NAME
70
+ # NOTE: remove_unused_tags cannot be used, because tag is deleted before assign for tagging
71
+ # @see https://github.com/mbleigh/acts-as-taggable-on/issues/946
72
+ # NOTE2: merging tags is not compatible, too.
73
+ ActsAsTaggableOn.remove_unused_tags = false
88
74
 
89
75
  config.after_initialize do
90
76
  # engine_name could be used (additional_tags_plugin), but can
91
- # create some side effencts
77
+ # create some side effects
92
78
  plugin_id = 'additional_tags'
93
79
 
94
80
  # if plugin is already in plugins directory, use this and leave here
@@ -96,7 +82,7 @@ module AdditionalTags
96
82
 
97
83
  # gem is used as redmine plugin
98
84
  require File.expand_path '../init', __dir__
99
- AdditionalTags.setup
85
+ AdditionalTags.setup!
100
86
  Additionals::Gemify.install_assets plugin_id
101
87
  Additionals::Gemify.create_plugin_hint plugin_id
102
88
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :redmine do
4
+ namespace :additional_tags do
5
+ desc <<-DESCRIPTION
6
+ Remove unused tags.
7
+
8
+ Example:
9
+ bundle exec rake redmine:additional_tags:remove_unused_tags RAILS_ENV=production
10
+ DESCRIPTION
11
+ task remove_unused_tags: :environment do
12
+ AdditionalTags::Tags.remove_unused_tags
13
+
14
+ puts 'Unused tags has been removed.'
15
+ exit 0
16
+ end
17
+ end
18
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: additional_tags
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - AlphaNodes
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-22 00:00:00.000000000 Z
11
+ date: 2022-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acts-as-taggable-on
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '7.0'
19
+ version: '9.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '7.0'
26
+ version: '9.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redmine_plugin_kit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -60,7 +74,7 @@ extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - ".eslintrc.yml"
63
- - ".github/workflows/brakeman.yml"
77
+ - ".github/workflows/codeql-analysis.yml"
64
78
  - ".github/workflows/linters.yml"
65
79
  - ".github/workflows/tests.yml"
66
80
  - ".gitignore"
@@ -81,16 +95,21 @@ files:
81
95
  - app/models/migrate_tag.rb
82
96
  - app/models/migrate_tagging.rb
83
97
  - app/models/query_tags_column.rb
98
+ - app/views/additional_tags/_body_bottom.html.slim
84
99
  - app/views/additional_tags/_html_head.html.slim
85
100
  - app/views/additional_tags/_tag_list.html.slim
86
101
  - app/views/additional_tags/context_menu.html.slim
87
102
  - app/views/additional_tags/edit.html.slim
103
+ - app/views/additional_tags/index.api.rsb
88
104
  - app/views/additional_tags/merge.html.slim
89
105
  - app/views/additional_tags/settings/_general.html.slim
90
106
  - app/views/additional_tags/settings/_manage_tags.html.slim
91
107
  - app/views/additional_tags/settings/_settings.html.slim
92
108
  - app/views/auto_completes/_additional_tag_list.slim
109
+ - app/views/common/_tag_summary_block.html.slim
93
110
  - app/views/context_menus/_issues_tags.html.slim
111
+ - app/views/dashboards/blocks/_issue_tags.html.slim
112
+ - app/views/dashboards/blocks/_issue_tags_settings.html.slim
94
113
  - app/views/issue_tags/_edit_modal.html.slim
95
114
  - app/views/issue_tags/edit.js.erb
96
115
  - app/views/issues/_tags.html.slim
@@ -98,7 +117,6 @@ files:
98
117
  - app/views/issues/_tags_form.html.slim
99
118
  - app/views/issues/_tags_form_details.html.slim
100
119
  - app/views/issues/_tags_sidebar.html.slim
101
- - app/views/reports/_tags_simple.html.slim
102
120
  - app/views/wiki/_tags_form.html.slim
103
121
  - app/views/wiki/_tags_form_bottom.html.slim
104
122
  - app/views/wiki/_tags_show.html.slim
@@ -106,6 +124,7 @@ files:
106
124
  - app/views/wiki/tag_index.html.slim
107
125
  - assets/javascripts/tags.js
108
126
  - assets/stylesheets/tags.css
127
+ - config/initializers/zeitwerk.rb
109
128
  - config/locales/bg.yml
110
129
  - config/locales/cs.yml
111
130
  - config/locales/de.yml
@@ -126,7 +145,8 @@ files:
126
145
  - doc/images/additional-tags.gif
127
146
  - init.rb
128
147
  - lib/additional_tags.rb
129
- - lib/additional_tags/hooks.rb
148
+ - lib/additional_tags/hooks/model_hook.rb
149
+ - lib/additional_tags/hooks/view_hook.rb
130
150
  - lib/additional_tags/patches/agile_boards_controller_patch.rb
131
151
  - lib/additional_tags/patches/agile_query_patch.rb
132
152
  - lib/additional_tags/patches/agile_versions_controller_patch.rb
@@ -134,6 +154,7 @@ files:
134
154
  - lib/additional_tags/patches/auto_completes_controller_patch.rb
135
155
  - lib/additional_tags/patches/calendars_controller_patch.rb
136
156
  - lib/additional_tags/patches/dashboard_async_blocks_controller_patch.rb
157
+ - lib/additional_tags/patches/dashboard_content_patch.rb
137
158
  - lib/additional_tags/patches/dashboards_controller_patch.rb
138
159
  - lib/additional_tags/patches/gantts_controller_patch.rb
139
160
  - lib/additional_tags/patches/imports_controller_patch.rb
@@ -144,7 +165,6 @@ files:
144
165
  - lib/additional_tags/patches/my_controller_patch.rb
145
166
  - lib/additional_tags/patches/queries_helper_patch.rb
146
167
  - lib/additional_tags/patches/query_patch.rb
147
- - lib/additional_tags/patches/reports_controller_patch.rb
148
168
  - lib/additional_tags/patches/settings_controller_patch.rb
149
169
  - lib/additional_tags/patches/time_entry_patch.rb
150
170
  - lib/additional_tags/patches/time_entry_query_patch.rb
@@ -152,12 +172,14 @@ files:
152
172
  - lib/additional_tags/patches/timelog_controller_patch.rb
153
173
  - lib/additional_tags/patches/wiki_controller_patch.rb
154
174
  - lib/additional_tags/patches/wiki_page_patch.rb
175
+ - lib/additional_tags/plugin_version.rb
155
176
  - lib/additional_tags/tags.rb
156
- - lib/additional_tags/version.rb
177
+ - lib/tasks/additional_tags.rake
157
178
  homepage: https://github.com/alphanodes/additional_tags
158
179
  licenses:
159
180
  - GPL-2.0
160
- metadata: {}
181
+ metadata:
182
+ rubygems_mfa_required: 'true'
161
183
  post_install_message:
162
184
  rdoc_options: []
163
185
  require_paths:
@@ -166,14 +188,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
188
  requirements:
167
189
  - - ">="
168
190
  - !ruby/object:Gem::Version
169
- version: '2.5'
191
+ version: '2.7'
170
192
  required_rubygems_version: !ruby/object:Gem::Requirement
171
193
  requirements:
172
194
  - - ">="
173
195
  - !ruby/object:Gem::Version
174
196
  version: '0'
175
197
  requirements: []
176
- rubygems_version: 3.1.6
198
+ rubygems_version: 3.3.7
177
199
  signing_key:
178
200
  specification_version: 4
179
201
  summary: Redmine plugin for adding tag functionality