additional_tags 1.0.2 → 1.0.5
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/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/linters.yml +6 -2
- data/.github/workflows/tests.yml +8 -6
- data/.gitignore +2 -1
- data/.rubocop.yml +31 -6
- data/README.md +17 -18
- data/additional_tags.gemspec +6 -4
- data/app/controllers/additional_tags_controller.rb +23 -0
- data/app/helpers/additional_tags_helper.rb +60 -19
- data/app/helpers/additional_tags_issues_helper.rb +12 -2
- data/app/helpers/additional_tags_wiki_helper.rb +1 -25
- data/app/jobs/additional_tags_remove_unused_tag_job.rb +5 -0
- data/app/views/additional_tags/_body_bottom.html.slim +19 -0
- data/app/views/additional_tags/_html_head.html.slim +1 -4
- data/app/views/additional_tags/_tag_list.html.slim +1 -1
- data/app/views/additional_tags/context_menu.html.slim +1 -4
- data/app/views/additional_tags/index.api.rsb +5 -0
- data/app/views/additional_tags/settings/_manage_tags.html.slim +23 -23
- data/app/views/common/_tag_summary_block.html.slim +11 -0
- data/app/views/context_menus/_issues_tags.html.slim +1 -1
- data/app/views/dashboards/blocks/_issue_tags.html.slim +58 -0
- data/app/views/dashboards/blocks/_issue_tags_settings.html.slim +20 -0
- data/app/views/issue_tags/_edit_modal.html.slim +4 -2
- data/app/views/issues/_tags_sidebar.html.slim +4 -1
- data/assets/javascripts/tags.js +4 -3
- data/assets/stylesheets/tags.css +27 -13
- data/config/initializers/zeitwerk.rb +4 -0
- data/config/locales/bg.yml +5 -0
- data/config/locales/cs.yml +5 -0
- data/config/locales/de.yml +5 -0
- data/config/locales/en.yml +5 -0
- data/config/locales/es.yml +5 -0
- data/config/locales/fr.yml +5 -0
- data/config/locales/it.yml +5 -0
- data/config/locales/ja.yml +5 -0
- data/config/locales/ko.yml +5 -0
- data/config/locales/pl.yml +5 -0
- data/config/locales/pt-BR.yml +5 -0
- data/config/locales/ru.yml +28 -23
- data/config/routes.rb +1 -1
- data/db/migrate/20201123093214_migrate_existing_tags.rb +1 -1
- data/init.rb +9 -7
- data/lib/additional_tags/hooks/model_hook.rb +11 -0
- data/lib/additional_tags/hooks/view_hook.rb +79 -0
- data/lib/additional_tags/patches/auto_completes_controller_patch.rb +5 -6
- data/lib/additional_tags/patches/dashboard_content_patch.rb +28 -0
- data/lib/additional_tags/patches/issue_patch.rb +25 -28
- data/lib/additional_tags/patches/query_patch.rb +10 -3
- data/lib/additional_tags/patches/wiki_controller_patch.rb +1 -1
- data/lib/additional_tags/patches/wiki_page_patch.rb +50 -1
- data/lib/additional_tags/plugin_version.rb +7 -0
- data/lib/additional_tags/tags.rb +54 -4
- data/lib/additional_tags.rb +51 -65
- data/lib/tasks/additional_tags.rake +18 -0
- metadata +34 -12
- data/.github/workflows/brakeman.yml +0 -34
- data/app/views/reports/_tags_simple.html.slim +0 -11
- data/lib/additional_tags/hooks.rb +0 -75
- data/lib/additional_tags/patches/reports_controller_patch.rb +0 -34
- 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
|
29
|
-
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
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,
|
71
|
-
|
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:,
|
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}
|
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
|
-
|
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 =
|
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
|
98
|
+
send :safe_attributes_without_tags=, attrs, user
|
50
99
|
end
|
51
100
|
|
52
101
|
private
|
data/lib/additional_tags/tags.rb
CHANGED
@@ -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.
|
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(
|
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.
|
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)
|
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
|
|
data/lib/additional_tags.rb
CHANGED
@@ -1,94 +1,80 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
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
|
-
|
15
|
-
|
16
|
-
|
22
|
+
loader.incompatible? %w[redmine_tags
|
23
|
+
redmine_tagging
|
24
|
+
redmineup_tags]
|
17
25
|
|
18
26
|
# Patches
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
#
|
55
|
-
|
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
|
-
|
78
|
-
|
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 '
|
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
|
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.
|
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:
|
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: '
|
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: '
|
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/
|
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
|
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.
|
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.
|
198
|
+
rubygems_version: 3.3.7
|
177
199
|
signing_key:
|
178
200
|
specification_version: 4
|
179
201
|
summary: Redmine plugin for adding tag functionality
|