additional_tags 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/brakeman.yml +38 -0
- data/.github/workflows/linters.yml +41 -0
- data/.github/workflows/tests.yml +139 -0
- data/.gitignore +8 -0
- data/.rubocop.yml +75 -0
- data/.slim-lint.yml +25 -0
- data/.stylelintrc.json +163 -0
- data/LICENSE +339 -0
- data/README.md +126 -0
- data/Rakefile +11 -0
- data/additional_tags.gemspec +28 -0
- data/app/controllers/additional_tags_controller.rb +80 -0
- data/app/controllers/issue_tags_controller.rb +48 -0
- data/app/helpers/additional_tags_helper.rb +197 -0
- data/app/helpers/additional_tags_issues_helper.rb +43 -0
- data/app/helpers/additional_tags_wiki_helper.rb +17 -0
- data/app/jobs/additional_tags_job.rb +3 -0
- data/app/jobs/additional_tags_remove_unused_tag_job.rb +5 -0
- data/app/models/migrate_tag.rb +4 -0
- data/app/models/migrate_tagging.rb +5 -0
- data/app/views/additional_tags/_html_head.html.slim +6 -0
- data/app/views/additional_tags/_tag_list.html.slim +35 -0
- data/app/views/additional_tags/context_menu.html.slim +16 -0
- data/app/views/additional_tags/edit.html.slim +14 -0
- data/app/views/additional_tags/merge.html.slim +17 -0
- data/app/views/additional_tags/settings/_general.html.slim +45 -0
- data/app/views/additional_tags/settings/_manage_tags.html.slim +35 -0
- data/app/views/additional_tags/settings/_settings.html.slim +9 -0
- data/app/views/auto_completes/_additional_tag_list.slim +1 -0
- data/app/views/context_menus/_issues_tags.html.slim +10 -0
- data/app/views/issue_tags/_edit_modal.html.slim +30 -0
- data/app/views/issue_tags/edit.js.erb +2 -0
- data/app/views/issues/_tags.html.slim +8 -0
- data/app/views/issues/_tags_bulk_edit.html.slim +7 -0
- data/app/views/issues/_tags_form.html.slim +11 -0
- data/app/views/issues/_tags_form_details.html.slim +7 -0
- data/app/views/issues/_tags_sidebar.html.slim +5 -0
- data/app/views/reports/_tags_simple.html.slim +11 -0
- data/app/views/wiki/_tags_form.html.slim +7 -0
- data/app/views/wiki/_tags_form_bottom.html.slim +5 -0
- data/app/views/wiki/_tags_show.html.slim +9 -0
- data/app/views/wiki/_tags_sidebar.html.slim +4 -0
- data/app/views/wiki/tag_index.html.slim +21 -0
- data/assets/javascripts/tags.js +19 -0
- data/assets/stylesheets/tags.css +119 -0
- data/config/locales/bg.yml +33 -0
- data/config/locales/cs.yml +33 -0
- data/config/locales/de.yml +33 -0
- data/config/locales/en.yml +33 -0
- data/config/locales/es.yml +33 -0
- data/config/locales/fr.yml +33 -0
- data/config/locales/it.yml +33 -0
- data/config/locales/ja.yml +33 -0
- data/config/locales/ko.yml +33 -0
- data/config/locales/pl.yml +33 -0
- data/config/locales/pt-BR.yml +33 -0
- data/config/locales/ru.yml +33 -0
- data/config/routes.rb +31 -0
- data/config/settings.yml +9 -0
- data/db/migrate/20201116145429_acts_as_taggable_migration.rb +40 -0
- data/db/migrate/20201123093214_migrate_existing_tags.rb +39 -0
- data/doc/images/additional-tags-framework.png +0 -0
- data/doc/images/additional-tags.gif +0 -0
- data/init.rb +31 -0
- data/lib/additional_tags.rb +107 -0
- data/lib/additional_tags/hooks.rb +63 -0
- data/lib/additional_tags/patches/agile_boards_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/agile_query_patch.rb +41 -0
- data/lib/additional_tags/patches/agile_versions_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/agile_versions_query_patch.rb +11 -0
- data/lib/additional_tags/patches/auto_completes_controller_patch.rb +42 -0
- data/lib/additional_tags/patches/calendars_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/dashboard_async_blocks_controller_patch.rb +11 -0
- data/lib/additional_tags/patches/dashboards_controller_patch.rb +11 -0
- data/lib/additional_tags/patches/gantts_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/imports_controller_patch.rb +12 -0
- data/lib/additional_tags/patches/issue_patch.rb +95 -0
- data/lib/additional_tags/patches/issue_query_patch.rb +55 -0
- data/lib/additional_tags/patches/issues_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/journal_patch.rb +18 -0
- data/lib/additional_tags/patches/my_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/queries_helper_patch.rb +40 -0
- data/lib/additional_tags/patches/reports_controller_patch.rb +32 -0
- data/lib/additional_tags/patches/settings_controller_patch.rb +12 -0
- data/lib/additional_tags/patches/time_entry_patch.rb +19 -0
- data/lib/additional_tags/patches/time_entry_query_patch.rb +53 -0
- data/lib/additional_tags/patches/time_report_patch.rb +46 -0
- data/lib/additional_tags/patches/timelog_controller_patch.rb +14 -0
- data/lib/additional_tags/patches/wiki_controller_patch.rb +63 -0
- data/lib/additional_tags/patches/wiki_page_patch.rb +39 -0
- data/lib/additional_tags/tags.rb +134 -0
- data/lib/additional_tags/version.rb +3 -0
- metadata +177 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
class ActsAsTaggableMigration < ActiveRecord::Migration[5.2]
|
2
|
+
def up
|
3
|
+
create_table ActsAsTaggableOn.tags_table do |t|
|
4
|
+
t.string :name, index: { unique: true }
|
5
|
+
t.integer :taggings_count, default: 0
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table ActsAsTaggableOn.taggings_table do |t|
|
10
|
+
t.references :tag, foreign_key: { to_table: ActsAsTaggableOn.tags_table }, index: false
|
11
|
+
|
12
|
+
# You should make sure that the column created is
|
13
|
+
# long enough to store the required class names.
|
14
|
+
t.references :taggable, polymorphic: true
|
15
|
+
t.references :tagger, polymorphic: true
|
16
|
+
|
17
|
+
# Limit is created to prevent MySQL error on index
|
18
|
+
# length for MyISAM table type: http://bit.ly/vgW2Ql
|
19
|
+
t.string :context, limit: 128
|
20
|
+
|
21
|
+
t.datetime :created_at
|
22
|
+
|
23
|
+
t.index %i[tag_id taggable_id taggable_type context tagger_id tagger_type], unique: true, name: 'ataggings_idx'
|
24
|
+
t.index %i[taggable_id taggable_type context], name: 'ataggings_taggable_context_idx'
|
25
|
+
t.index :taggable_type
|
26
|
+
t.index :context
|
27
|
+
t.index %i[tagger_id tagger_type]
|
28
|
+
t.index %i[taggable_id taggable_type tagger_id context], name: 'ataggings_idy'
|
29
|
+
end
|
30
|
+
|
31
|
+
return unless ActsAsTaggableOn::Utils.using_mysql?
|
32
|
+
|
33
|
+
execute("ALTER TABLE #{ActsAsTaggableOn.tags_table} MODIFY name varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;")
|
34
|
+
end
|
35
|
+
|
36
|
+
def down
|
37
|
+
drop_table ActsAsTaggableOn.taggings_table
|
38
|
+
drop_table ActsAsTaggableOn.tags_table
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class MigrateExistingTags < ActiveRecord::Migration[5.2]
|
2
|
+
def up
|
3
|
+
return unless table_exists?(MigrateTag.table_name) && table_exists?(MigrateTagging.table_name)
|
4
|
+
|
5
|
+
excluded_taggable_types = %w[Question Contact DriveEntry]
|
6
|
+
|
7
|
+
MigrateTag.all.each do |old_tag|
|
8
|
+
ActsAsTaggableOn::Tagging.transaction do
|
9
|
+
tag = ActsAsTaggableOn::Tag.find_by name: old_tag.name
|
10
|
+
cnt = 0
|
11
|
+
old_tag.migrate_taggings.each do |tagging|
|
12
|
+
next if excluded_taggable_types.include? tagging.taggable_type
|
13
|
+
|
14
|
+
tag = ActsAsTaggableOn::Tag.create!(name: old_tag.name) if cnt.zero? && tag.nil?
|
15
|
+
context = tagging.respond_to?('context') && tagging.context.present? ? tagging.context : 'tags'
|
16
|
+
|
17
|
+
# old data can include dups
|
18
|
+
next if ActsAsTaggableOn::Tagging.exists? tag_id: tag.id,
|
19
|
+
taggable_id: tagging.taggable_id,
|
20
|
+
taggable_type: tagging.taggable_type,
|
21
|
+
context: context
|
22
|
+
|
23
|
+
ActsAsTaggableOn::Tagging.create! tag_id: tag.id,
|
24
|
+
taggable_id: tagging.taggable_id,
|
25
|
+
taggable_type: tagging.taggable_type,
|
26
|
+
context: context,
|
27
|
+
created_at: tagging.created_at
|
28
|
+
cnt += 1
|
29
|
+
end
|
30
|
+
|
31
|
+
ActsAsTaggableOn::Tag.reset_counters(tag.id, :taggings) unless tag.nil?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def down
|
37
|
+
# to nothing
|
38
|
+
end
|
39
|
+
end
|
Binary file
|
Binary file
|
data/init.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
Redmine::Plugin.register :additional_tags do
|
2
|
+
name 'Additional Tags'
|
3
|
+
author 'AlphaNodes GmbH'
|
4
|
+
description 'Redmine tagging support'
|
5
|
+
version AdditionalTags::VERSION
|
6
|
+
url 'https://github.com/alphanodes/additional_tags/'
|
7
|
+
author_url 'https://alphanodes.com/'
|
8
|
+
directory __dir__
|
9
|
+
|
10
|
+
requires_redmine version_or_higher: '4.1'
|
11
|
+
|
12
|
+
settings default: Additionals.load_settings('additional_tags'),
|
13
|
+
partial: 'additional_tags/settings/settings'
|
14
|
+
|
15
|
+
project_module :issue_tracking do
|
16
|
+
permission :create_issue_tags, {}
|
17
|
+
permission :edit_issue_tags, {}
|
18
|
+
permission :view_issue_tags, {}, read: true
|
19
|
+
end
|
20
|
+
|
21
|
+
project_module :wiki do
|
22
|
+
permission :add_wiki_tags, wiki: %i[update_tags]
|
23
|
+
end
|
24
|
+
|
25
|
+
menu :admin_menu,
|
26
|
+
:tags, { controller: 'settings', action: 'plugin', id: 'additional_tags' }, caption: :field_tags
|
27
|
+
end
|
28
|
+
|
29
|
+
Rails.configuration.to_prepare do
|
30
|
+
AdditionalTags.setup
|
31
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'additional_tags/version'
|
2
|
+
require 'additional_tags/tags'
|
3
|
+
|
4
|
+
module AdditionalTags
|
5
|
+
TAG_TABLE_NAME = 'additional_tags'.freeze
|
6
|
+
TAGGING_TABLE_NAME = 'additional_taggings'.freeze
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def setup
|
10
|
+
raise 'Please install additionals plugin (https://github.com/alphanodes/additionals)' unless Redmine::Plugin.installed? 'additionals'
|
11
|
+
|
12
|
+
Additionals.incompatible_plugins(%w[redmine_tags
|
13
|
+
redmine_tagging
|
14
|
+
redmineup_tags], 'additional_tags')
|
15
|
+
|
16
|
+
# Patches
|
17
|
+
AutoCompletesController.include AdditionalTags::Patches::AutoCompletesControllerPatch
|
18
|
+
CalendarsController.include AdditionalTags::Patches::CalendarsControllerPatch
|
19
|
+
DashboardsController.include AdditionalTags::Patches::DashboardsControllerPatch
|
20
|
+
DashboardAsyncBlocksController.include AdditionalTags::Patches::DashboardAsyncBlocksControllerPatch
|
21
|
+
GanttsController.include AdditionalTags::Patches::GanttsControllerPatch
|
22
|
+
MyController.include AdditionalTags::Patches::MyControllerPatch
|
23
|
+
Issue.include AdditionalTags::Patches::IssuePatch
|
24
|
+
Journal.include AdditionalTags::Patches::JournalPatch
|
25
|
+
IssuesController.include AdditionalTags::Patches::IssuesControllerPatch
|
26
|
+
ImportsController.include AdditionalTags::Patches::ImportsControllerPatch
|
27
|
+
QueriesHelper.include AdditionalTags::Patches::QueriesHelperPatch
|
28
|
+
ReportsController.include AdditionalTags::Patches::ReportsControllerPatch
|
29
|
+
SettingsController.include AdditionalTags::Patches::SettingsControllerPatch
|
30
|
+
Redmine::Helpers::TimeReport.include AdditionalTags::Patches::TimeReportPatch
|
31
|
+
TimeEntry.include AdditionalTags::Patches::TimeEntryPatch
|
32
|
+
TimelogController.include AdditionalTags::Patches::TimelogControllerPatch
|
33
|
+
WikiController.include AdditionalTags::Patches::WikiControllerPatch
|
34
|
+
WikiPage.include AdditionalTags::Patches::WikiPagePatch
|
35
|
+
|
36
|
+
# because of this bug: https://www.redmine.org/issues/33290
|
37
|
+
if Additionals.redmine_database_ready? TAG_TABLE_NAME
|
38
|
+
IssueQuery.include AdditionalTags::Patches::IssueQueryPatch
|
39
|
+
TimeEntryQuery.include AdditionalTags::Patches::TimeEntryQueryPatch
|
40
|
+
|
41
|
+
if Redmine::Plugin.installed? 'redmine_agile'
|
42
|
+
AgileQuery.include AdditionalTags::Patches::AgileQueryPatch
|
43
|
+
AgileBoardsController.include AdditionalTags::Patches::AgileBoardsControllerPatch
|
44
|
+
if AGILE_VERSION_TYPE == 'PRO version'
|
45
|
+
AgileVersionsController.include AdditionalTags::Patches::AgileVersionsControllerPatch
|
46
|
+
AgileVersionsQuery.include AdditionalTags::Patches::AgileVersionsQueryPatch
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Hooks
|
52
|
+
require_dependency 'additional_tags/hooks'
|
53
|
+
end
|
54
|
+
|
55
|
+
# support with default setting as fall back
|
56
|
+
def setting(value)
|
57
|
+
if settings.key? value
|
58
|
+
settings[value]
|
59
|
+
else
|
60
|
+
Additionals.load_settings('additional_tags')[value]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def setting?(value)
|
65
|
+
Additionals.true? settings[value]
|
66
|
+
end
|
67
|
+
|
68
|
+
def show_sidebar_tags?
|
69
|
+
setting(:tags_sidebar).present? && setting(:tags_sidebar) != 'none'
|
70
|
+
end
|
71
|
+
|
72
|
+
def sql_for_tags_field(klass, operator, value)
|
73
|
+
compare = operator.eql?('=') ? 'IN' : 'NOT IN'
|
74
|
+
ids_list = klass.tagged_with(value).map(&:id).push(0).join(',')
|
75
|
+
"(#{klass.table_name}.id #{compare} (#{ids_list})) "
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def settings
|
81
|
+
Setting[:plugin_additional_tags]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Run the classic redmine plugin initializer after rails boot
|
86
|
+
class Plugin < ::Rails::Engine
|
87
|
+
require 'acts-as-taggable-on'
|
88
|
+
|
89
|
+
ActsAsTaggableOn.tags_table = TAG_TABLE_NAME
|
90
|
+
ActsAsTaggableOn.taggings_table = TAGGING_TABLE_NAME
|
91
|
+
|
92
|
+
config.after_initialize do
|
93
|
+
# engine_name could be used (additional_tags_plugin), but can
|
94
|
+
# create some side effencts
|
95
|
+
plugin_id = 'additional_tags'
|
96
|
+
|
97
|
+
# if plugin is already in plugins directory, use this and leave here
|
98
|
+
next if Redmine::Plugin.installed? plugin_id
|
99
|
+
|
100
|
+
# gem is used as redmine plugin
|
101
|
+
require File.expand_path '../init', __dir__
|
102
|
+
AdditionalTags.setup
|
103
|
+
Additionals::Gemify.install_assets plugin_id
|
104
|
+
Additionals::Gemify.create_plugin_hint plugin_id
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module AdditionalTags
|
2
|
+
class AdditionalTagsHookListener < Redmine::Hook::ViewListener
|
3
|
+
render_on :view_issues_bulk_edit_details_bottom,
|
4
|
+
partial: 'issues/tags_form_details',
|
5
|
+
locals: { tags_form: 'issues/tags_bulk_edit' }
|
6
|
+
render_on :view_issues_context_menu_end, partial: 'context_menus/issues_tags'
|
7
|
+
render_on :view_issues_form_details_bottom,
|
8
|
+
partial: 'issues/tags_form_details',
|
9
|
+
locals: { tags_form: 'issues/tags_form' }
|
10
|
+
render_on :view_issues_show_details_bottom, partial: 'issues/tags'
|
11
|
+
render_on :view_issues_sidebar_planning_bottom, partial: 'issues/tags_sidebar'
|
12
|
+
render_on :view_layouts_base_html_head, partial: 'additional_tags/html_head'
|
13
|
+
render_on :view_reports_issue_report_split_content_right, partial: 'tags_simple'
|
14
|
+
render_on :view_wiki_form_bottom, partial: 'tags_form_bottom'
|
15
|
+
render_on :view_wiki_show_bottom, partial: 'tags_show'
|
16
|
+
render_on :view_wiki_show_sidebar_bottom, partial: 'tags_sidebar'
|
17
|
+
|
18
|
+
def controller_issues_edit_before_save(context = {})
|
19
|
+
tags_journal context[:issue], context[:params]
|
20
|
+
end
|
21
|
+
|
22
|
+
def controller_issues_bulk_edit_before_save(context = {})
|
23
|
+
tags_journal context[:issue], context[:params]
|
24
|
+
end
|
25
|
+
|
26
|
+
# this hook is missing in redmine core at the moment
|
27
|
+
def view_issue_pdf_fields(context = {})
|
28
|
+
issue = context[:issue]
|
29
|
+
right = context[:right]
|
30
|
+
|
31
|
+
if AdditionalTags.setting?(:active_issue_tags) &&
|
32
|
+
User.current.allowed_to?(:view_issue_tags, issue.project)
|
33
|
+
right << [l(:field_tag_list), issue.tag_list]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# this hook is missing in redmine core at the moment
|
38
|
+
def view_wiki_pdf_buttom(context = {})
|
39
|
+
page = context[:page]
|
40
|
+
pdf = context[:pdf]
|
41
|
+
|
42
|
+
return if page.tag_list.blank?
|
43
|
+
|
44
|
+
pdf.ln 5
|
45
|
+
pdf.SetFontStyle 'B', 9
|
46
|
+
pdf.RDMCell 190, 5, l(:field_tag_list), 'B'
|
47
|
+
|
48
|
+
pdf.ln
|
49
|
+
pdf.SetFontStyle '', 8
|
50
|
+
pdf.RDMCell 190, 5, page.tag_list.join(', ')
|
51
|
+
pdf.ln
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def tags_journal(issue, params)
|
57
|
+
return unless params && params[:issue] && params[:issue][:tag_list]
|
58
|
+
|
59
|
+
issue.tags_to_journal Issue.find_by(id: issue.id)&.tag_list&.to_s,
|
60
|
+
issue.tag_list.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module AdditionalTags
|
2
|
+
module Patches
|
3
|
+
module AgileQueryPatch
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include AdditionalsQuery
|
8
|
+
include InstanceMethods
|
9
|
+
|
10
|
+
alias_method :initialize_available_filters_without_tags, :initialize_available_filters
|
11
|
+
alias_method :initialize_available_filters, :initialize_available_filters_with_tags
|
12
|
+
|
13
|
+
add_available_column QueryColumn.new(:tags)
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
def sql_for_tags_field(_field, operator, value)
|
18
|
+
case operator
|
19
|
+
when '=', '!'
|
20
|
+
issues = Issue.tagged_with(value.clone)
|
21
|
+
when '!*'
|
22
|
+
issues = Issue.joins(:tags).uniq
|
23
|
+
else
|
24
|
+
issues = Issue.tagged_with(ActsAsTaggableOn::Tag.all.map(&:to_s), any: true)
|
25
|
+
end
|
26
|
+
|
27
|
+
compare = operator.include?('!') ? 'NOT IN' : 'IN'
|
28
|
+
ids_list = issues.collect(&:id).push(0).join(',')
|
29
|
+
"( #{Issue.table_name}.id #{compare} (#{ids_list}) ) "
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize_available_filters_with_tags
|
33
|
+
initialize_available_filters_without_tags
|
34
|
+
|
35
|
+
initialize_tags_filter if !available_filters.key?('tags') &&
|
36
|
+
User.current.allowed_to?(:view_issue_tags, project, global: true)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module AdditionalTags
|
2
|
+
module Patches
|
3
|
+
module AutoCompletesControllerPatch
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include InstanceMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module InstanceMethods
|
11
|
+
def issue_tags
|
12
|
+
suggestion_order = AdditionalTags.setting(:tags_suggestion_order) || 'name'
|
13
|
+
@name = (params[:q] || params[:term]).to_s.strip
|
14
|
+
@tags = Issue.available_tags name_like: @name,
|
15
|
+
sort_by: suggestion_order,
|
16
|
+
order: (suggestion_order == 'name' ? 'ASC' : 'DESC')
|
17
|
+
|
18
|
+
@tags = AdditionalTags::Tags.sort_tag_list @tags if suggestion_order == 'name'
|
19
|
+
|
20
|
+
render layout: false, partial: 'additional_tag_list', locals: { unsorted: true }
|
21
|
+
end
|
22
|
+
|
23
|
+
def wiki_tags
|
24
|
+
@name = params[:q].to_s
|
25
|
+
@tags = WikiPage.available_tags project: @project, name_like: @name
|
26
|
+
render layout: false, partial: 'additional_tag_list', locals: { unsorted: true }
|
27
|
+
end
|
28
|
+
|
29
|
+
def all_tags
|
30
|
+
return render_403 unless User.current.admin?
|
31
|
+
|
32
|
+
@name = params[:q].to_s
|
33
|
+
sql_for_where = "LOWER(#{ActiveRecord::Base.connection.quote_table_name(ActsAsTaggableOn.tags_table)}.name) LIKE ?"
|
34
|
+
@tags = ActsAsTaggableOn::Tag.where(sql_for_where, "%#{@name.downcase}%")
|
35
|
+
.order(name: :asc)
|
36
|
+
|
37
|
+
render layout: false, partial: 'additional_tag_list', locals: { unsorted: true }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|