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
@@ -1,29 +1,29 @@
|
|
1
1
|
- tags = manageable_tags
|
2
2
|
- if tags.present?
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
.autoscroll
|
4
|
+
table.list.issues
|
5
|
+
thead
|
6
|
+
tr
|
7
|
+
th.checkbox.hide-when-print
|
8
|
+
= check_box_tag 'ids[]', '', false, class: 'toggle-selection',
|
9
|
+
title: "#{l :button_check_all}/#{l :button_uncheck_all}"
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
data: { confirm: l(:text_are_you_sure) }, class: 'icon icon-del'
|
11
|
+
th = l :field_name
|
12
|
+
- manageable_tag_columns.each do |_column, column_values|
|
13
|
+
th = column_values[:label]
|
14
|
+
th
|
15
|
+
tbody
|
16
|
+
- tags.each do |tag|
|
17
|
+
tr.hascontextmenu id="#{tag.id}"
|
18
|
+
td.checkbox.hide-when-print
|
19
|
+
= check_box_tag 'ids[]', tag.id, false, id: nil
|
20
|
+
td = additional_tag_link tag, link: edit_additional_tag_path(tag)
|
21
|
+
- manageable_tag_column_values(tag).each do |column|
|
22
|
+
td = column
|
23
|
+
td.buttons
|
24
|
+
= link_to l(:button_edit), edit_additional_tag_path(tag),
|
25
|
+
class: 'icon icon-edit'
|
26
|
+
= delete_link additional_tags_path(ids: tag)
|
27
27
|
- else
|
28
28
|
p.nodata = l :label_no_data
|
29
29
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
h3 = block_definition[:label]
|
2
|
+
|
3
|
+
- open_issues_only = RedminePluginKit.true? settings[:open_issues_only]
|
4
|
+
- tags = Issue.available_tags project: @project, open_issues_only: open_issues_only
|
5
|
+
- counts = AdditionalTags::Tags.entity_group_by scope: Issue.group_by_status_with_tags(@project),
|
6
|
+
tags: tags,
|
7
|
+
statuses: { true => :closed, false => :open },
|
8
|
+
group_id_is_bool: true
|
9
|
+
|
10
|
+
= render partial: 'common/tag_summary_block',
|
11
|
+
locals: { tags: tags,
|
12
|
+
entities_label: l(:label_issue_plural),
|
13
|
+
totals_link: link_to_issue_tags_totals(entries: counts,
|
14
|
+
project: @project,
|
15
|
+
open_issues_only: open_issues_only) }
|
16
|
+
|
17
|
+
- if RedminePluginKit.true? settings[:with_table_of_values]
|
18
|
+
- if tags.present?
|
19
|
+
- tags = sort_tags_for_list tags.to_a
|
20
|
+
table.list.tags
|
21
|
+
thead
|
22
|
+
tr
|
23
|
+
th = l :field_name
|
24
|
+
- if open_issues_only
|
25
|
+
th = l :label_quantity
|
26
|
+
- else
|
27
|
+
th = l :label_open_issues_plural
|
28
|
+
th = l :label_closed_issues_plural
|
29
|
+
th = l :label_total
|
30
|
+
tbody
|
31
|
+
- tags.each do |tag|
|
32
|
+
tr
|
33
|
+
td.name = additional_tag_link tag,
|
34
|
+
tag_action: 'index',
|
35
|
+
tag_controller: 'issues',
|
36
|
+
filter: issue_tag_status_filter(open_issues_only: open_issues_only),
|
37
|
+
use_colors: RedminePluginKit.true?(settings[:use_colors])
|
38
|
+
- unless open_issues_only
|
39
|
+
td.value = additional_tag_link tag,
|
40
|
+
tag_action: 'index',
|
41
|
+
tag_controller: 'issues',
|
42
|
+
filter: issue_tag_status_filter(operator: 'o'),
|
43
|
+
use_colors: false,
|
44
|
+
name: counts[tag.name][:open]
|
45
|
+
td.value = additional_tag_link tag,
|
46
|
+
tag_action: 'index',
|
47
|
+
tag_controller: 'issues',
|
48
|
+
filter: issue_tag_status_filter(operator: 'c'),
|
49
|
+
use_colors: false,
|
50
|
+
name: counts[tag.name][:closed]
|
51
|
+
td.value = additional_tag_link tag,
|
52
|
+
tag_action: 'index',
|
53
|
+
tag_controller: 'issues',
|
54
|
+
filter: issue_tag_status_filter(open_issues_only: open_issues_only),
|
55
|
+
use_colors: false,
|
56
|
+
name: open_issues_only ? counts[tag.name][:open] : counts[tag.name][:total]
|
57
|
+
- else
|
58
|
+
p.nodata = l :label_no_data
|
@@ -0,0 +1,20 @@
|
|
1
|
+
.box.tabular.settings
|
2
|
+
p
|
3
|
+
= additionals_settings_checkbox :with_table_of_values,
|
4
|
+
active_value: settings[:with_table_of_values],
|
5
|
+
tag_name: "settings[#{block}][with_table_of_values]"
|
6
|
+
|
7
|
+
/ p
|
8
|
+
/ = additionals_settings_checkbox :with_chart,
|
9
|
+
/ active_value: settings[:with_chart],
|
10
|
+
/ tag_name: "settings[#{block}][with_chart]"
|
11
|
+
|
12
|
+
p
|
13
|
+
= additionals_settings_checkbox :open_issues_only,
|
14
|
+
active_value: settings[:open_issues_only],
|
15
|
+
tag_name: "settings[#{block}][open_issues_only]"
|
16
|
+
|
17
|
+
p
|
18
|
+
= additionals_settings_checkbox :use_colors,
|
19
|
+
active_value: settings[:use_colors],
|
20
|
+
tag_name: "settings[#{block}][use_colors]"
|
@@ -9,7 +9,7 @@ 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) do
|
12
|
+
= form_tag issue_tags_path(ids: @issue_ids, search: params[:search]) do
|
13
13
|
fieldset.box
|
14
14
|
legend = l :field_tags
|
15
15
|
#issue_tags
|
@@ -22,9 +22,11 @@ h3.title = l :label_add_tags
|
|
22
22
|
tags: User.current.allowed_to?(:create_issue_tags, @project)
|
23
23
|
p.most_used_tags
|
24
24
|
= safe_join @most_used_tags.collect { |t| tag.span t.name, class: 'most_used_tag' }, ', '
|
25
|
-
= javascript_tag "var mostUsedTags = #{@most_used_tags.map(&:name)}"
|
26
25
|
|
27
26
|
.buttons
|
28
27
|
= submit_tag l(:button_add), name: nil
|
29
28
|
'
|
30
29
|
= link_to_function l(:button_cancel), 'hideModal(this);'
|
30
|
+
|
31
|
+
javascript:
|
32
|
+
var mostUsedTags = #{raw @most_used_tags.map(&:name)};
|
@@ -1,5 +1,8 @@
|
|
1
1
|
- if AdditionalTags.setting?(:active_issue_tags) && \
|
2
|
-
User.current.allowed_to?(:view_issue_tags, @project, global: true) &&
|
2
|
+
User.current.allowed_to?(:view_issue_tags, @project, global: true) && \
|
3
|
+
defined?(sidebar_tags) && \
|
4
|
+
sidebar_tags.present?
|
5
|
+
|
3
6
|
.sidebar-tags
|
4
7
|
h3 = l :field_tags
|
5
8
|
= render_sidebar_tags
|
data/assets/javascripts/tags.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
/* global mostUsedTags:writable */
|
2
|
+
$(function() {
|
3
|
+
$('body').on('click', '.most_used_tags .most_used_tag', function(e) {
|
3
4
|
var $tagsSelect = $('select#issue_tag_list');
|
4
5
|
var tag = e.target.innerText;
|
5
6
|
if ($tagsSelect.find('option[value=\'' + tag + '\']').length === 0) {
|
@@ -7,7 +8,7 @@ $(function () {
|
|
7
8
|
$tagsSelect.append(newOption).trigger('change');
|
8
9
|
}
|
9
10
|
|
10
|
-
|
11
|
+
mostUsedTags = $.grep(mostUsedTags, function(t) { return t != tag; });
|
11
12
|
var tagsHtml = mostUsedTags.map(function(tag) {
|
12
13
|
return '<span class="most_used_tag">' + tag + '</span>';
|
13
14
|
}).join(', ');
|
data/assets/stylesheets/tags.css
CHANGED
@@ -26,8 +26,8 @@ ul.tags li { margin: 0.25em 0; }
|
|
26
26
|
|
27
27
|
span.additional-tag-label-color {
|
28
28
|
display: inline-block;
|
29
|
-
margin-bottom:
|
30
|
-
border-radius:
|
29
|
+
margin-bottom: 3px !important;
|
30
|
+
border-radius: 0.75rem !important;
|
31
31
|
}
|
32
32
|
|
33
33
|
td.tags span.additional-tag-label-color {
|
@@ -37,27 +37,41 @@ td.tags span.additional-tag-label-color {
|
|
37
37
|
}
|
38
38
|
|
39
39
|
.additional-tag-label-color {
|
40
|
-
padding:
|
41
|
-
|
40
|
+
padding: 0 5px;
|
41
|
+
line-height: initial;
|
42
|
+
font-size: 0.7rem !important;
|
42
43
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
43
|
-
border-radius:
|
44
|
+
border-radius: 0.75rem;
|
44
45
|
}
|
45
46
|
|
46
|
-
.additional-tag-label-color
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
.additional-tag-label-color .tag-count {
|
48
|
+
display: inline-block;
|
49
|
+
background: #fff;
|
50
|
+
color: #1f1f1f;
|
51
|
+
padding-right: 5px;
|
52
|
+
border-top-right-radius: 0.7rem;
|
53
|
+
border-bottom-right-radius: 0.7rem;
|
54
|
+
margin-right: -5px;
|
55
|
+
padding-left: 3px;
|
56
|
+
}
|
57
|
+
|
58
|
+
.tag-label .tag-count {
|
59
|
+
background: #f1f5fa;
|
60
|
+
border-radius: 5px;
|
61
|
+
padding: 0 5px;
|
62
|
+
color: #666;
|
63
|
+
border: 1px solid #ddd;
|
64
|
+
vertical-align: middle;
|
52
65
|
}
|
53
66
|
|
54
67
|
.additional-tag-label-color .tag-count,
|
55
68
|
.tag-label .tag-count {
|
56
|
-
font-size: 0.
|
69
|
+
font-size: 0.7rem;
|
57
70
|
margin-left: 0.5em;
|
58
71
|
}
|
59
72
|
|
60
|
-
span.additional-tag-label-color:hover a
|
73
|
+
span.additional-tag-label-color:hover a,
|
74
|
+
.tag-label .tag-count:hover a {
|
61
75
|
text-decoration: none !important;
|
62
76
|
}
|
63
77
|
|
data/config/locales/bg.yml
CHANGED
@@ -31,3 +31,8 @@ bg:
|
|
31
31
|
tags_sort_by_name: "Име"
|
32
32
|
label_tags_sort_by: "Сортиране на маркерите по"
|
33
33
|
label_tags_suggestion_order: "Ред на предлагане"
|
34
|
+
label_with_table_of_values: "С таблица на стойността"
|
35
|
+
label_with_chart: "С графиком"
|
36
|
+
label_amount_tags: "Теги Сумма"
|
37
|
+
label_amount_entities_with_tags: "Сумма %{name} с тегами"
|
38
|
+
label_quantity: "Количество"
|
data/config/locales/cs.yml
CHANGED
@@ -31,3 +31,8 @@ cs:
|
|
31
31
|
tags_sort_by_name: "Název"
|
32
32
|
label_tags_sort_by: "Řazení značek podle"
|
33
33
|
label_tags_suggestion_order: "Objednávka návrhu"
|
34
|
+
label_with_table_of_values: "S tabulkou hodnot"
|
35
|
+
label_with_chart: "S grafem"
|
36
|
+
label_amount_tags: "Částka TAGy"
|
37
|
+
label_amount_entities_with_tags: "Částka %{name} s TAGy"
|
38
|
+
label_quantity: "Množství"
|
data/config/locales/de.yml
CHANGED
@@ -31,3 +31,8 @@ de:
|
|
31
31
|
tags_sort_by_name: Name
|
32
32
|
label_tags_sort_by: Sortiere TAGs nach
|
33
33
|
label_tags_suggestion_order: Reihenfolge der Vorschläge
|
34
|
+
label_with_table_of_values: Mit Wertetabelle
|
35
|
+
label_with_chart: Mit Chart
|
36
|
+
label_amount_tags: Anzahl TAGs
|
37
|
+
label_amount_entities_with_tags: Anzahl %{name} mit TAGs
|
38
|
+
label_quantity: Anzahl
|
data/config/locales/en.yml
CHANGED
@@ -31,3 +31,8 @@ en:
|
|
31
31
|
tags_sort_by_name: "Name"
|
32
32
|
label_tags_sort_by: "Sort tags by"
|
33
33
|
label_tags_suggestion_order: "Suggestion order"
|
34
|
+
label_with_table_of_values: "With table of values"
|
35
|
+
label_with_chart: "With chart"
|
36
|
+
label_amount_tags: "Amount tags"
|
37
|
+
label_amount_entities_with_tags: "Amount %{name} with tags"
|
38
|
+
label_quantity: "Quantity"
|
data/config/locales/es.yml
CHANGED
@@ -31,3 +31,8 @@ es:
|
|
31
31
|
tags_sort_by_name: "Nombre"
|
32
32
|
label_tags_sort_by: "Ordenar las tags por"
|
33
33
|
label_tags_suggestion_order: "Orden de sugerencia"
|
34
|
+
label_with_table_of_values: "Con tabla de valores"
|
35
|
+
label_with_chart: "Con tabla"
|
36
|
+
label_amount_tags: "Valor tags"
|
37
|
+
label_amount_entities_with_tags: "Cantidad %{name} con tags"
|
38
|
+
label_quantity: "Ctd."
|
data/config/locales/fr.yml
CHANGED
@@ -31,3 +31,8 @@ fr:
|
|
31
31
|
tags_sort_by_name: "Nom"
|
32
32
|
label_tags_sort_by: "Trier les balises par"
|
33
33
|
label_tags_suggestion_order: "Ordre de suggestion"
|
34
|
+
label_with_table_of_values: "Avec tableau de valeur"
|
35
|
+
label_with_chart: "Avec tableau"
|
36
|
+
label_amount_tags: "Montant tags"
|
37
|
+
label_amount_entities_with_tags: "Montant %{name} avec tags"
|
38
|
+
label_quantity: "Quantité"
|
data/config/locales/it.yml
CHANGED
@@ -31,3 +31,8 @@ it:
|
|
31
31
|
tags_sort_by_name: "Nome"
|
32
32
|
label_tags_sort_by: "Ordina i tag per"
|
33
33
|
label_tags_suggestion_order: "Ordine di suggerimento"
|
34
|
+
label_with_table_of_values: With table of values
|
35
|
+
label_with_chart: With chart
|
36
|
+
label_amount_tags: Amount tags
|
37
|
+
label_amount_entities_with_tags: Amount %{name} with tags
|
38
|
+
label_quantity: "Numero"
|
data/config/locales/ja.yml
CHANGED
@@ -31,3 +31,8 @@ ja:
|
|
31
31
|
tags_sort_by_name: "名前"
|
32
32
|
label_tags_sort_by: "タグを並べ替える"
|
33
33
|
label_tags_suggestion_order: "ご提案の順番"
|
34
|
+
label_with_table_of_values: "価値観のテーブル付き"
|
35
|
+
label_with_chart: "チャート付き"
|
36
|
+
label_amount_tags: "金額 tags"
|
37
|
+
label_amount_entities_with_tags: "金額 %{name} tags付き"
|
38
|
+
label_quantity: "数量"
|
data/config/locales/ko.yml
CHANGED
@@ -31,3 +31,8 @@ ko:
|
|
31
31
|
tags_sort_by_name: "이름"
|
32
32
|
label_tags_sort_by: "태그 정렬 기준"
|
33
33
|
label_tags_suggestion_order: "제안 순서"
|
34
|
+
label_with_table_of_values: "가치 테이블"
|
35
|
+
label_with_chart: "차트 포함"
|
36
|
+
label_amount_tags: "금액 태그"
|
37
|
+
label_amount_entities_with_tags: "TAG가 있는 금액 %{name}"
|
38
|
+
label_quantity: "수량"
|
data/config/locales/pl.yml
CHANGED
@@ -31,3 +31,8 @@ pl:
|
|
31
31
|
tags_sort_by_name: "Nazwa"
|
32
32
|
label_tags_sort_by: "Sortuj znaczniki według"
|
33
33
|
label_tags_suggestion_order: "Zamówienie ofertowe"
|
34
|
+
label_with_table_of_values: "Z tabelą wartości"
|
35
|
+
label_with_chart: "Z wykresem"
|
36
|
+
label_amount_tags: "Kwota Tags"
|
37
|
+
label_amount_entities_with_tags: "Kwota %{name} z Tags"
|
38
|
+
label_quantity: "Ilość"
|
data/config/locales/pt-BR.yml
CHANGED
@@ -31,3 +31,8 @@ pt-BR:
|
|
31
31
|
tags_sort_by_name: "Nome"
|
32
32
|
label_tags_sort_by: "Ordenar tags por"
|
33
33
|
label_tags_suggestion_order: "Pedido de sugestão"
|
34
|
+
label_with_table_of_values: "Com tabela de valores"
|
35
|
+
label_with_chart: "Com gráfico"
|
36
|
+
label_amount_tags: "Valor Etiquetas"
|
37
|
+
label_amount_entities_with_tags: "Quantidade %{name} com etiquetas"
|
38
|
+
label_quantity: "Quantidade"
|
data/config/locales/ru.yml
CHANGED
@@ -1,33 +1,38 @@
|
|
1
1
|
ru:
|
2
|
-
field_tag_list:
|
3
|
-
field_tags:
|
4
|
-
field_issue_tags:
|
5
|
-
label_active_issue_tags: "Активировать теги
|
6
|
-
label_active_wiki_tags: "Активировать
|
7
|
-
label_add_tags: "
|
2
|
+
field_tag_list: Теги
|
3
|
+
field_tags: Теги
|
4
|
+
field_issue_tags: Теги задач
|
5
|
+
label_active_issue_tags: "Активировать теги задач"
|
6
|
+
label_active_wiki_tags: "Активировать теги вики"
|
7
|
+
label_add_tags: "Добавьте теги"
|
8
8
|
label_edit_tags: "Редактировать теги"
|
9
|
-
label_manage_tags: "
|
9
|
+
label_manage_tags: "Управление тегами"
|
10
10
|
label_merge_selected_tags: "Объединить выбранные теги"
|
11
|
-
label_open_issues_only: "Отображать только открытые
|
12
|
-
label_show_with_count: "
|
13
|
-
label_tags_tag: "
|
11
|
+
label_open_issues_only: "Отображать только открытые задачи"
|
12
|
+
label_show_with_count: "Отображать количество на теге"
|
13
|
+
label_tags_tag: "Тег"
|
14
14
|
label_use_colors: "Использовать цвета"
|
15
15
|
label_wiki_index_for_tag_html: "Вики-страницы с тегом <em>%{tag}</em>"
|
16
16
|
notice_failed_to_add_tags: "Не удалось добавить теги"
|
17
17
|
notice_tags_added: "Теги добавлены"
|
18
|
-
permission_add_wiki_tags: "
|
19
|
-
permission_create_issue_tags: "
|
20
|
-
permission_edit_issue_tags: "Редактирование
|
21
|
-
permission_view_issue_tags: "
|
22
|
-
tags_order_by_last_created: "
|
23
|
-
tags_order_by_count: "Наиболее часто
|
18
|
+
permission_add_wiki_tags: "Добавление тегов вики"
|
19
|
+
permission_create_issue_tags: "Добавление тегов задач"
|
20
|
+
permission_edit_issue_tags: "Редактирование тегов задач"
|
21
|
+
permission_view_issue_tags: "Просмотр тегов задач"
|
22
|
+
tags_order_by_last_created: "Недавно созданные"
|
23
|
+
tags_order_by_count: "Наиболее часто используемые"
|
24
24
|
tags_order_by_name: "Имя"
|
25
|
-
tags_sidebar_cloud: "
|
25
|
+
tags_sidebar_cloud: "Облако"
|
26
26
|
tags_sidebar_list: "Список"
|
27
27
|
tags_sidebar_none: "Нет"
|
28
|
-
tags_sidebar_simple_cloud: "
|
29
|
-
label_tags_sidebar: "
|
30
|
-
tags_sort_by_count: "
|
31
|
-
tags_sort_by_name: "
|
32
|
-
label_tags_sort_by: "Сортировать
|
33
|
-
label_tags_suggestion_order: "Порядок предложения"
|
28
|
+
tags_sidebar_simple_cloud: "Простое облако"
|
29
|
+
label_tags_sidebar: "Способ отображения тегов на боковой панели"
|
30
|
+
tags_sort_by_count: "Количеству"
|
31
|
+
tags_sort_by_name: "Имени"
|
32
|
+
label_tags_sort_by: "Сортировать теги по"
|
33
|
+
label_tags_suggestion_order: "Порядок предложения при вводе"
|
34
|
+
label_with_table_of_values: "С таблицей значений"
|
35
|
+
label_with_chart: "С графиком"
|
36
|
+
label_amount_tags: "Теги Сумма"
|
37
|
+
label_amount_entities_with_tags: "Сумма %{name} с тегами"
|
38
|
+
label_quantity: "Количество"
|
data/config/routes.rb
CHANGED
@@ -14,7 +14,7 @@ class MigrateExistingTags < ActiveRecord::Migration[5.2]
|
|
14
14
|
next if excluded_taggable_types.include? tagging.taggable_type
|
15
15
|
|
16
16
|
tag = ActsAsTaggableOn::Tag.create! name: old_tag.name if cnt.zero? && tag.nil?
|
17
|
-
context = tagging.respond_to?(
|
17
|
+
context = tagging.respond_to?(:context) && tagging.context.present? ? tagging.context : 'tags'
|
18
18
|
|
19
19
|
# old data can include dups
|
20
20
|
next if ActsAsTaggableOn::Tagging.exists? tag_id: tag.id,
|
data/init.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'additional_tags/plugin_version'
|
4
|
+
|
5
|
+
loader = RedminePluginKit::Loader.new plugin_id: 'additional_tags'
|
6
|
+
|
3
7
|
Redmine::Plugin.register :additional_tags do
|
4
8
|
name 'Additional Tags'
|
5
9
|
author 'AlphaNodes GmbH'
|
6
10
|
description 'Redmine tagging support'
|
7
|
-
version AdditionalTags::VERSION
|
11
|
+
version AdditionalTags::PluginVersion::VERSION
|
8
12
|
url 'https://github.com/alphanodes/additional_tags/'
|
9
|
-
author_url
|
13
|
+
author_url 'https://alphanodes.com/'
|
10
14
|
directory __dir__
|
11
15
|
|
12
|
-
requires_redmine version_or_higher: '
|
16
|
+
requires_redmine version_or_higher: '5.0'
|
13
17
|
|
14
|
-
settings default:
|
18
|
+
settings default: loader.default_settings,
|
15
19
|
partial: 'additional_tags/settings/settings'
|
16
20
|
|
17
21
|
project_module :issue_tracking do
|
@@ -30,6 +34,4 @@ Redmine::Plugin.register :additional_tags do
|
|
30
34
|
caption: :field_tags
|
31
35
|
end
|
32
36
|
|
33
|
-
|
34
|
-
AdditionalTags.setup
|
35
|
-
end
|
37
|
+
RedminePluginKit::Loader.persisting { loader.load_model_hooks! }
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AdditionalTags
|
4
|
+
module Hooks
|
5
|
+
class ViewHook < Redmine::Hook::ViewListener
|
6
|
+
render_on :view_issues_bulk_edit_details_bottom,
|
7
|
+
partial: 'issues/tags_form_details',
|
8
|
+
locals: { tags_form: 'issues/tags_bulk_edit' }
|
9
|
+
render_on :view_issues_context_menu_end, partial: 'context_menus/issues_tags'
|
10
|
+
render_on :view_issues_form_details_bottom,
|
11
|
+
partial: 'issues/tags_form_details',
|
12
|
+
locals: { tags_form: 'issues/tags_form' }
|
13
|
+
render_on :view_issues_show_details_bottom, partial: 'issues/tags'
|
14
|
+
render_on :view_issues_sidebar_planning_bottom, partial: 'issues/tags_sidebar'
|
15
|
+
render_on :view_layouts_base_html_head, partial: 'additional_tags/html_head'
|
16
|
+
render_on :view_layouts_base_body_bottom, partial: 'additional_tags/body_bottom'
|
17
|
+
render_on :view_wiki_form_bottom, partial: 'tags_form_bottom'
|
18
|
+
render_on :view_wiki_show_bottom, partial: 'tags_show'
|
19
|
+
render_on :view_wiki_show_sidebar_bottom, partial: 'wiki/tags_sidebar'
|
20
|
+
|
21
|
+
def controller_issues_edit_before_save(context = {})
|
22
|
+
tags_journal context[:issue], context[:params]
|
23
|
+
end
|
24
|
+
|
25
|
+
def controller_issues_bulk_edit_before_save(context = {})
|
26
|
+
issue = context[:issue]
|
27
|
+
params = context[:params]
|
28
|
+
|
29
|
+
issues_bulk_tags_fix issue, params
|
30
|
+
tags_journal issue, params
|
31
|
+
end
|
32
|
+
|
33
|
+
# this hook is missing in redmine core at the moment
|
34
|
+
def view_issue_pdf_fields(context = {})
|
35
|
+
issue = context[:issue]
|
36
|
+
right = context[:right]
|
37
|
+
|
38
|
+
if AdditionalTags.setting?(:active_issue_tags) &&
|
39
|
+
User.current.allowed_to?(:view_issue_tags, issue.project)
|
40
|
+
right << [l(:field_tag_list), issue.tag_list]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# this hook is missing in redmine core at the moment
|
45
|
+
def view_wiki_pdf_buttom(context = {})
|
46
|
+
page = context[:page]
|
47
|
+
pdf = context[:pdf]
|
48
|
+
|
49
|
+
return if page.tag_list.blank?
|
50
|
+
|
51
|
+
pdf.ln 5
|
52
|
+
pdf.SetFontStyle 'B', 9
|
53
|
+
pdf.RDMCell 190, 5, l(:field_tag_list), 'B'
|
54
|
+
|
55
|
+
pdf.ln
|
56
|
+
pdf.SetFontStyle '', 8
|
57
|
+
pdf.RDMCell 190, 5, page.tag_list.to_list
|
58
|
+
pdf.ln
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def issues_bulk_tags_fix(issue, params)
|
64
|
+
return unless params && params[:issue]
|
65
|
+
|
66
|
+
old_tags = issue.tags.map(&:name)
|
67
|
+
new_tags = Array(params[:issue][:tag_list]).reject(&:empty?)
|
68
|
+
issue.tag_list = (old_tags + new_tags).uniq
|
69
|
+
end
|
70
|
+
|
71
|
+
def tags_journal(issue, params)
|
72
|
+
return unless params && params[:issue] && params[:issue][:tag_list]
|
73
|
+
|
74
|
+
issue.tags_to_journal Issue.find_by(id: issue.id)&.tag_list&.to_s,
|
75
|
+
issue.tag_list.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -12,8 +12,7 @@ module AdditionalTags
|
|
12
12
|
module InstanceMethods
|
13
13
|
def issue_tags
|
14
14
|
suggestion_order = AdditionalTags.setting(:tags_suggestion_order) || 'name'
|
15
|
-
@
|
16
|
-
@tags = Issue.available_tags name_like: @name,
|
15
|
+
@tags = Issue.available_tags name_like: build_search_query_term(params),
|
17
16
|
sort_by: suggestion_order,
|
18
17
|
order: (suggestion_order == 'name' ? 'ASC' : 'DESC')
|
19
18
|
|
@@ -23,17 +22,17 @@ module AdditionalTags
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def wiki_tags
|
26
|
-
@
|
27
|
-
|
25
|
+
@tags = WikiPage.available_tags project: nil,
|
26
|
+
name_like: build_search_query_term(params)
|
28
27
|
render layout: false, partial: 'additional_tag_list', locals: { unsorted: true }
|
29
28
|
end
|
30
29
|
|
31
30
|
def all_tags
|
32
31
|
return render_403 unless User.current.admin?
|
33
32
|
|
34
|
-
|
33
|
+
q = build_search_query_term params
|
35
34
|
sql_for_where = "LOWER(#{ActiveRecord::Base.connection.quote_table_name ActsAsTaggableOn.tags_table}.name) LIKE ?"
|
36
|
-
@tags = ActsAsTaggableOn::Tag.where(sql_for_where, "%#{
|
35
|
+
@tags = ActsAsTaggableOn::Tag.where(sql_for_where, "%#{q.downcase}%")
|
37
36
|
.order(name: :asc)
|
38
37
|
|
39
38
|
render layout: false, partial: 'additional_tag_list', locals: { unsorted: true }
|