additional_tags 1.0.5 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/codeql-analysis.yml +6 -6
- data/.github/workflows/linters.yml +16 -4
- data/.github/workflows/tests.yml +7 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +9 -6
- data/.stylelintrc.json +12 -155
- data/README.md +28 -9
- data/app/controllers/additional_tags_controller.rb +10 -10
- data/app/controllers/issue_tags_controller.rb +3 -1
- data/app/helpers/additional_tags_helper.rb +39 -30
- data/app/helpers/additional_tags_issues_helper.rb +1 -3
- data/app/helpers/additional_tags_wiki_helper.rb +16 -10
- data/app/jobs/additional_tags_remove_unused_tag_job.rb +11 -6
- data/app/models/additional_tag.rb +98 -0
- data/app/views/additional_tags/_tag_list.html.slim +12 -6
- data/app/views/additional_tags/merge.html.slim +0 -1
- data/app/views/additional_tags/settings/_general.html.slim +7 -1
- data/app/views/additional_tags/settings/_manage_tags.html.slim +8 -1
- data/app/views/context_menus/_issues_tags.html.slim +7 -1
- data/app/views/dashboards/blocks/_issue_tags.html.slim +9 -7
- data/app/views/issue_tags/_edit_modal.html.slim +7 -7
- data/app/views/issue_tags/edit.js.erb +1 -1
- data/app/views/issues/_tags.html.slim +12 -7
- data/app/views/issues/_tags_bulk_edit.html.slim +2 -1
- data/app/views/issues/_tags_form_details.html.slim +1 -2
- data/app/views/wiki/_tags_form.html.slim +4 -0
- data/app/views/wiki/_tags_form_bottom.html.slim +1 -2
- data/app/views/wiki/_tags_show.html.slim +7 -7
- data/app/views/wiki/tag_index.html.slim +2 -2
- data/assets/javascripts/tags.js +3 -3
- data/assets/stylesheets/tags.css +41 -16
- data/config/locales/bg.yml +18 -11
- data/config/locales/cs.yml +19 -12
- data/config/locales/de.yml +19 -12
- data/config/locales/en.yml +19 -12
- data/config/locales/es.yml +19 -12
- data/config/locales/fr.yml +19 -12
- data/config/locales/it.yml +19 -12
- data/config/locales/ja.yml +18 -11
- data/config/locales/ko.yml +18 -11
- data/config/locales/pl.yml +19 -12
- data/config/locales/pt-BR.yml +18 -11
- data/config/locales/ru.yml +34 -27
- data/config/settings.yml +5 -5
- data/doc/images/additional-tags-framework.png +0 -0
- data/doc/images/additional-tags.gif +0 -0
- data/doc/images/tag-overview.png +0 -0
- data/lib/additional_tags/hooks/view_hook.rb +15 -2
- data/lib/additional_tags/patches/issue_patch.rb +53 -7
- data/lib/additional_tags/patches/issue_query_patch.rb +18 -0
- data/lib/additional_tags/patches/queries_helper_patch.rb +1 -3
- data/lib/additional_tags/patches/query_patch.rb +23 -2
- data/lib/additional_tags/patches/wiki_page_patch.rb +8 -2
- data/lib/additional_tags/plugin_version.rb +1 -1
- data/lib/additional_tags/tags.rb +35 -14
- data/lib/additional_tags.rb +5 -0
- data/package.json +8 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d187e05dfc7655030d62f26afc35392085f43cbac4bb4b4d654da66c643cd58f
|
4
|
+
data.tar.gz: 88901a08b7c4b38df8b65fd20282f5e4aae393866e5accf7c3a096d7c82f4788
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34e99763fad968c1f2498dc73b662fb756c4b436e0a4521acd731674c3bebdf8bee52cc55e995457908d39816b61a230fd29d4ac1f3a1662a3e12bb886e6d60e
|
7
|
+
data.tar.gz: 4aeb8f7bcbaad55d596dd6f816cedbde29f1c707748ff9ce275f7f131959df258c10e2683ce279cf4c26f8a459d53992ae6e4202d9ff9963a637d88b85661c98
|
@@ -13,10 +13,10 @@ name: "CodeQL"
|
|
13
13
|
|
14
14
|
on:
|
15
15
|
push:
|
16
|
-
branches: [
|
16
|
+
branches: [ main ]
|
17
17
|
pull_request:
|
18
18
|
# The branches below must be a subset of the branches above
|
19
|
-
branches: [
|
19
|
+
branches: [ main ]
|
20
20
|
schedule:
|
21
21
|
- cron: '35 20 * * 2'
|
22
22
|
|
@@ -38,11 +38,11 @@ jobs:
|
|
38
38
|
|
39
39
|
steps:
|
40
40
|
- name: Checkout repository
|
41
|
-
uses: actions/checkout@
|
41
|
+
uses: actions/checkout@v3
|
42
42
|
|
43
43
|
# Initializes the CodeQL tools for scanning.
|
44
44
|
- name: Initialize CodeQL
|
45
|
-
uses: github/codeql-action/init@
|
45
|
+
uses: github/codeql-action/init@v2
|
46
46
|
with:
|
47
47
|
languages: ${{ matrix.language }}
|
48
48
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
@@ -53,7 +53,7 @@ jobs:
|
|
53
53
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
54
54
|
# If this step fails, then you should remove it and run the build manually (see below)
|
55
55
|
- name: Autobuild
|
56
|
-
uses: github/codeql-action/autobuild@
|
56
|
+
uses: github/codeql-action/autobuild@v2
|
57
57
|
|
58
58
|
# ℹ️ Command-line programs to run using the OS shell.
|
59
59
|
# 📚 https://git.io/JvXDl
|
@@ -67,4 +67,4 @@ jobs:
|
|
67
67
|
# make release
|
68
68
|
|
69
69
|
- name: Perform CodeQL Analysis
|
70
|
-
uses: github/codeql-action/analyze@
|
70
|
+
uses: github/codeql-action/analyze@v2
|
@@ -8,7 +8,7 @@ jobs:
|
|
8
8
|
runs-on: ubuntu-latest
|
9
9
|
|
10
10
|
steps:
|
11
|
-
- uses: actions/checkout@
|
11
|
+
- uses: actions/checkout@v3
|
12
12
|
|
13
13
|
- name: Install package dependencies
|
14
14
|
run: >
|
@@ -22,10 +22,9 @@ jobs:
|
|
22
22
|
- name: Setup Ruby
|
23
23
|
uses: ruby/setup-ruby@v1
|
24
24
|
with:
|
25
|
-
ruby-version: 3.
|
26
|
-
bundler-cache: true
|
25
|
+
ruby-version: 3.1
|
27
26
|
|
28
|
-
- name:
|
27
|
+
- name: Run bundle install
|
29
28
|
run: |
|
30
29
|
bundle install --jobs 4 --retry 3
|
31
30
|
|
@@ -41,3 +40,16 @@ jobs:
|
|
41
40
|
- name: Run Brakeman
|
42
41
|
run: |
|
43
42
|
bundle exec brakeman -5
|
43
|
+
|
44
|
+
- name: Setup node
|
45
|
+
uses: actions/setup-node@v2
|
46
|
+
with:
|
47
|
+
node-version: '16'
|
48
|
+
|
49
|
+
- run: yarn install
|
50
|
+
|
51
|
+
- name: Run Stylelint
|
52
|
+
run: node_modules/.bin/stylelint assets/stylesheets/
|
53
|
+
|
54
|
+
- name: Run ESLint
|
55
|
+
run: node_modules/.bin/eslint assets/javascripts/
|
data/.github/workflows/tests.yml
CHANGED
@@ -10,9 +10,12 @@ jobs:
|
|
10
10
|
|
11
11
|
strategy:
|
12
12
|
matrix:
|
13
|
-
ruby: ['2.7', '3.0', '3.1']
|
13
|
+
ruby: ['2.7', '3.0', '3.1', '3.2']
|
14
14
|
redmine: ['5.0-stable', 'master']
|
15
15
|
db: ['postgres', 'mysql']
|
16
|
+
exclude:
|
17
|
+
- ruby: '3.2'
|
18
|
+
redmine: 5.0-stable
|
16
19
|
fail-fast: false
|
17
20
|
|
18
21
|
services:
|
@@ -51,20 +54,20 @@ jobs:
|
|
51
54
|
if: matrix.db == 'mysql'
|
52
55
|
|
53
56
|
- name: Checkout Redmine
|
54
|
-
uses: actions/checkout@
|
57
|
+
uses: actions/checkout@v3
|
55
58
|
with:
|
56
59
|
repository: redmine/redmine
|
57
60
|
ref: ${{ matrix.redmine }}
|
58
61
|
path: redmine
|
59
62
|
|
60
63
|
- name: Checkout additionals
|
61
|
-
uses: actions/checkout@
|
64
|
+
uses: actions/checkout@v3
|
62
65
|
with:
|
63
66
|
repository: AlphaNodes/additionals
|
64
67
|
path: redmine/plugins/additionals
|
65
68
|
|
66
69
|
- name: Checkout additional_tags
|
67
|
-
uses: actions/checkout@
|
70
|
+
uses: actions/checkout@v3
|
68
71
|
with:
|
69
72
|
path: redmine/plugins/additional_tags
|
70
73
|
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -7,6 +7,7 @@ AllCops:
|
|
7
7
|
TargetRubyVersion: 2.7
|
8
8
|
TargetRailsVersion: 6.1
|
9
9
|
NewCops: enable
|
10
|
+
ActiveSupportExtensionsEnabled: true
|
10
11
|
|
11
12
|
Rails:
|
12
13
|
Enabled: true
|
@@ -118,18 +119,20 @@ Style/MethodCallWithArgsParentheses:
|
|
118
119
|
AllowParenthesesInChaining: true
|
119
120
|
EnforcedStyle: omit_parentheses
|
120
121
|
|
121
|
-
Style/HashTransformKeys:
|
122
|
-
Enabled: false
|
123
|
-
|
124
|
-
Style/HashTransformValues:
|
125
|
-
Enabled: false
|
126
|
-
|
127
122
|
Naming/VariableNumber:
|
128
123
|
Enabled: true
|
129
124
|
Exclude:
|
130
125
|
- 'test/**/*'
|
131
126
|
|
127
|
+
Layout/LineContinuationLeadingSpace:
|
128
|
+
Enabled: false
|
129
|
+
|
132
130
|
# see https://github.com/rubocop/rubocop-rails/issues/578
|
133
131
|
# redmine does not use load_defaults: https://rails.rubystyle.guide/#config-defaults
|
134
132
|
Rails/RedundantPresenceValidationOnBelongsTo:
|
135
133
|
Enabled: false
|
134
|
+
|
135
|
+
# see https://github.com/rubocop/rubocop-rails/issues/825
|
136
|
+
# should be removed and corrected in code, if this bug is fixed
|
137
|
+
Rails/ActionControllerFlashBeforeRender:
|
138
|
+
Enabled: false
|
data/.stylelintrc.json
CHANGED
@@ -1,163 +1,20 @@
|
|
1
1
|
{
|
2
|
+
"extends": "stylelint-config-standard",
|
2
3
|
"rules": {
|
3
|
-
"
|
4
|
-
"
|
5
|
-
"
|
6
|
-
"comment-no-empty": true,
|
7
|
-
"declaration-block-no-duplicate-properties": [
|
4
|
+
"string-quotes": "single",
|
5
|
+
"selector-class-pattern": "^([a-z][a-z0-9]*)(-[a-z0-9]+)*$|block_column",
|
6
|
+
"font-family-no-missing-generic-family-keyword": [
|
8
7
|
true,
|
9
8
|
{
|
10
|
-
"
|
11
|
-
"
|
9
|
+
"ignoreFontFamilies": [
|
10
|
+
"Font Awesome 5 Free",
|
11
|
+
"Font Awesome 5 Brands",
|
12
|
+
"Apple Color Emoji",
|
13
|
+
"Segoe UI Emoji",
|
14
|
+
"Segoe UI Symbol",
|
15
|
+
"Noto Color Emoji"
|
12
16
|
]
|
13
17
|
}
|
14
|
-
]
|
15
|
-
"declaration-block-no-redundant-longhand-properties": true,
|
16
|
-
"declaration-block-no-shorthand-property-overrides": true,
|
17
|
-
"font-family-no-duplicate-names": true,
|
18
|
-
"font-family-no-missing-generic-family-keyword": true,
|
19
|
-
"function-calc-no-unspaced-operator": true,
|
20
|
-
"function-linear-gradient-no-nonstandard-direction": true,
|
21
|
-
"keyframe-declaration-no-important": true,
|
22
|
-
"media-feature-name-no-unknown": true,
|
23
|
-
"no-descending-specificity": true,
|
24
|
-
"no-duplicate-at-import-rules": true,
|
25
|
-
"no-duplicate-selectors": true,
|
26
|
-
"no-empty-source": true,
|
27
|
-
"no-extra-semicolons": true,
|
28
|
-
"no-invalid-double-slash-comments": true,
|
29
|
-
"property-no-unknown": true,
|
30
|
-
"selector-pseudo-class-no-unknown": true,
|
31
|
-
"selector-pseudo-element-no-unknown": true,
|
32
|
-
"selector-type-no-unknown": true,
|
33
|
-
"string-no-newline": true,
|
34
|
-
"unit-no-unknown": true,
|
35
|
-
"at-rule-empty-line-before": [
|
36
|
-
"always",
|
37
|
-
{
|
38
|
-
"except": [
|
39
|
-
"blockless-after-same-name-blockless",
|
40
|
-
"first-nested"
|
41
|
-
],
|
42
|
-
"ignore": [
|
43
|
-
"after-comment"
|
44
|
-
]
|
45
|
-
}
|
46
|
-
],
|
47
|
-
"at-rule-name-case": "lower",
|
48
|
-
"at-rule-name-space-after": "always-single-line",
|
49
|
-
"at-rule-semicolon-newline-after": "always",
|
50
|
-
"block-closing-brace-empty-line-before": "never",
|
51
|
-
"block-closing-brace-newline-after": "always",
|
52
|
-
"block-closing-brace-newline-before": "always-multi-line",
|
53
|
-
"block-closing-brace-space-before": "always-single-line",
|
54
|
-
"block-opening-brace-newline-after": "always-multi-line",
|
55
|
-
"block-opening-brace-space-after": "always-single-line",
|
56
|
-
"block-opening-brace-space-before": "always",
|
57
|
-
"color-hex-case": "lower",
|
58
|
-
"color-hex-length": "short",
|
59
|
-
"comment-empty-line-before": [
|
60
|
-
"always",
|
61
|
-
{
|
62
|
-
"except": [
|
63
|
-
"first-nested"
|
64
|
-
],
|
65
|
-
"ignore": [
|
66
|
-
"stylelint-commands"
|
67
|
-
]
|
68
|
-
}
|
69
|
-
],
|
70
|
-
"comment-whitespace-inside": "always",
|
71
|
-
"custom-property-empty-line-before": [
|
72
|
-
"always",
|
73
|
-
{
|
74
|
-
"except": [
|
75
|
-
"after-custom-property",
|
76
|
-
"first-nested"
|
77
|
-
],
|
78
|
-
"ignore": [
|
79
|
-
"after-comment",
|
80
|
-
"inside-single-line-block"
|
81
|
-
]
|
82
|
-
}
|
83
|
-
],
|
84
|
-
"declaration-bang-space-after": "never",
|
85
|
-
"declaration-bang-space-before": "always",
|
86
|
-
"declaration-block-semicolon-newline-after": "always-multi-line",
|
87
|
-
"declaration-block-semicolon-space-after": "always-single-line",
|
88
|
-
"declaration-block-semicolon-space-before": "never",
|
89
|
-
"declaration-block-single-line-max-declarations": 1,
|
90
|
-
"declaration-block-trailing-semicolon": "always",
|
91
|
-
"declaration-colon-newline-after": "always-multi-line",
|
92
|
-
"declaration-colon-space-after": "always-single-line",
|
93
|
-
"declaration-colon-space-before": "never",
|
94
|
-
"declaration-empty-line-before": [
|
95
|
-
"always",
|
96
|
-
{
|
97
|
-
"except": [
|
98
|
-
"after-declaration",
|
99
|
-
"first-nested"
|
100
|
-
],
|
101
|
-
"ignore": [
|
102
|
-
"after-comment",
|
103
|
-
"inside-single-line-block"
|
104
|
-
]
|
105
|
-
}
|
106
|
-
],
|
107
|
-
"function-comma-newline-after": "always-multi-line",
|
108
|
-
"function-comma-space-after": "always-single-line",
|
109
|
-
"function-comma-space-before": "never",
|
110
|
-
"function-max-empty-lines": 0,
|
111
|
-
"function-name-case": "lower",
|
112
|
-
"function-parentheses-newline-inside": "always-multi-line",
|
113
|
-
"function-parentheses-space-inside": "never-single-line",
|
114
|
-
"function-whitespace-after": "always",
|
115
|
-
"indentation": 2,
|
116
|
-
"length-zero-no-unit": true,
|
117
|
-
"max-empty-lines": 1,
|
118
|
-
"media-feature-colon-space-after": "always",
|
119
|
-
"media-feature-colon-space-before": "never",
|
120
|
-
"media-feature-name-case": "lower",
|
121
|
-
"media-feature-parentheses-space-inside": "never",
|
122
|
-
"media-feature-range-operator-space-after": "always",
|
123
|
-
"media-feature-range-operator-space-before": "always",
|
124
|
-
"media-query-list-comma-newline-after": "always-multi-line",
|
125
|
-
"media-query-list-comma-space-after": "always-single-line",
|
126
|
-
"media-query-list-comma-space-before": "never",
|
127
|
-
"no-eol-whitespace": true,
|
128
|
-
"no-missing-end-of-source-newline": true,
|
129
|
-
"number-leading-zero": "always",
|
130
|
-
"number-no-trailing-zeros": true,
|
131
|
-
"property-case": "lower",
|
132
|
-
"rule-empty-line-before": [
|
133
|
-
"always-multi-line",
|
134
|
-
{
|
135
|
-
"except": [
|
136
|
-
"first-nested"
|
137
|
-
],
|
138
|
-
"ignore": [
|
139
|
-
"after-comment"
|
140
|
-
]
|
141
|
-
}
|
142
|
-
],
|
143
|
-
"selector-attribute-brackets-space-inside": "never",
|
144
|
-
"selector-attribute-operator-space-after": "never",
|
145
|
-
"selector-attribute-operator-space-before": "never",
|
146
|
-
"selector-combinator-space-after": "always",
|
147
|
-
"selector-combinator-space-before": "always",
|
148
|
-
"selector-descendant-combinator-no-non-space": true,
|
149
|
-
"selector-list-comma-newline-after": "always",
|
150
|
-
"selector-list-comma-space-before": "never",
|
151
|
-
"selector-max-empty-lines": 0,
|
152
|
-
"selector-pseudo-class-case": "lower",
|
153
|
-
"selector-pseudo-class-parentheses-space-inside": "never",
|
154
|
-
"selector-pseudo-element-case": "lower",
|
155
|
-
"selector-pseudo-element-colon-notation": "double",
|
156
|
-
"selector-type-case": "lower",
|
157
|
-
"unit-case": "lower",
|
158
|
-
"value-list-comma-newline-after": "always-multi-line",
|
159
|
-
"value-list-comma-space-after": "always-single-line",
|
160
|
-
"value-list-comma-space-before": "never",
|
161
|
-
"value-list-max-empty-lines": 0
|
18
|
+
]
|
162
19
|
}
|
163
20
|
}
|
data/README.md
CHANGED
@@ -4,16 +4,35 @@
|
|
4
4
|
|
5
5
|
## Features
|
6
6
|
|
7
|
-
- Tags for issues
|
8
|
-
-
|
7
|
+
- Tags for issues. To use them you need to:
|
8
|
+
- *Activate issue tags* in the plugin configuration
|
9
|
+
- and update your role permissions in the Redmine administration *Roles & permissions / Issue tracking*.
|
10
|
+
- Tags for wiki pages. To use them you need to:
|
11
|
+
- *Activate wiki tags* in the plugin configuration
|
12
|
+
- and update your role permissions in the Redmine administration *Roles & permissions / Wiki*
|
13
|
+
- Available role permissions for issue tags (section *Issue tracking*):
|
14
|
+
- Add issue tags
|
15
|
+
- Edit issue tags
|
16
|
+
- Display issue tags
|
17
|
+
- Available role permissions wiki tags (section *Wiki*):
|
18
|
+
- Add wiki tags
|
19
|
+
- Managing tags centrally in the plugin settings (edit, delete, merge)-
|
20
|
+
- Grouped tags.
|
21
|
+
- Grouping of tags possible, when using a colon in tag (all tags with same base name get the same color). Typo example: ``Plugin:HRM``
|
22
|
+
- Scoped tags:
|
23
|
+
- Grouping of tags via *Scoped tags* possible, when using two colons in tag. Typo example: ``Product::Sprint 1``
|
24
|
+
- Only one tag of the same base name is allowed for an entity
|
25
|
+
- Base name and tag value are displayed seperatly
|
9
26
|
- Accented and non-latin characters supported for tag order
|
10
|
-
-
|
11
|
-
-
|
12
|
-
|
13
|
-
- Custom tags and tagging tables (additional_tags and additional_taggings). If a other plugin
|
14
|
-
used tags or tagging tables for issue or wiki tagging, there tags will be migrated automatically
|
27
|
+
- Color theme selection possible
|
28
|
+
- Custom tags and tagging tables (additional_tags and additional_taggings). If another plugin
|
29
|
+
used tags or tagging tables for issue or wiki tagging, tags will be migrated automatically there
|
15
30
|
- Based on the very popular [acts-as-taggable-on](https://github.com/mbleigh/acts-as-taggable-on)
|
16
31
|
|
32
|
+
![screenshot](https://raw.githubusercontent.com/AlphaNodes/additional_tags/master/doc/images/tag-overview.png)
|
33
|
+
|
34
|
+
The screenshot shows: regular tags, grouped tags and scoped tags. The colors are assigned randomly. But you can change the color by choosing a *Color theme* in the plugin settings.
|
35
|
+
|
17
36
|
![screenshot](https://raw.githubusercontent.com/AlphaNodes/additional_tags/master/doc/images/additional-tags.gif)
|
18
37
|
|
19
38
|
Other plugins use additional_tags as framework in order to support tags for their entities.
|
@@ -71,14 +90,14 @@ git clone https://github.com/alphanodes/additionals.git plugins/additionals
|
|
71
90
|
git clone https://github.com/alphanodes/additional_tags.git plugins/additional_tags
|
72
91
|
```
|
73
92
|
|
74
|
-
### 2. Install dependencies and migrate database
|
93
|
+
### 2. Install dependencies and migrate database
|
75
94
|
|
76
95
|
```shell
|
77
96
|
bundle install
|
78
97
|
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
|
79
98
|
```
|
80
99
|
|
81
|
-
### 3. Restart your Redmine web server
|
100
|
+
### 3. Restart your Redmine web server
|
82
101
|
|
83
102
|
## Running tests
|
84
103
|
|
@@ -33,15 +33,6 @@ class AdditionalTagsController < ApplicationController
|
|
33
33
|
|
34
34
|
def edit; end
|
35
35
|
|
36
|
-
def destroy
|
37
|
-
@tags.each do |tag|
|
38
|
-
tag.reload.destroy
|
39
|
-
rescue ::ActiveRecord::RecordNotFound
|
40
|
-
Rails.logger.warn "Tag #{tag} could not be deleted"
|
41
|
-
end
|
42
|
-
redirect_back_or_default @tag_list_path
|
43
|
-
end
|
44
|
-
|
45
36
|
def update
|
46
37
|
@tag.name = params[:tag][:name] if params[:tag]
|
47
38
|
if @tag.save
|
@@ -54,11 +45,20 @@ class AdditionalTagsController < ApplicationController
|
|
54
45
|
end
|
55
46
|
else
|
56
47
|
respond_to do |format|
|
57
|
-
format.html { render
|
48
|
+
format.html { render :edit }
|
58
49
|
end
|
59
50
|
end
|
60
51
|
end
|
61
52
|
|
53
|
+
def destroy
|
54
|
+
@tags.each do |tag|
|
55
|
+
tag.reload.destroy!
|
56
|
+
rescue ::ActiveRecord::RecordNotFound, ::ActiveRecord::RecordNotDestroyed
|
57
|
+
Rails.logger.warn "Tag #{tag} could not be deleted"
|
58
|
+
end
|
59
|
+
redirect_back_or_default @tag_list_path
|
60
|
+
end
|
61
|
+
|
62
62
|
def context_menu
|
63
63
|
@tag = @tags.first if @tags.size == 1
|
64
64
|
@back = back_url
|
@@ -19,6 +19,7 @@ class IssueTagsController < ApplicationController
|
|
19
19
|
|
20
20
|
@issue_tags.sort!
|
21
21
|
@most_used_tags = Issue.available_tags.most_used 10
|
22
|
+
@append = params[:append] == 'true'
|
22
23
|
end
|
23
24
|
|
24
25
|
def update
|
@@ -33,7 +34,8 @@ class IssueTagsController < ApplicationController
|
|
33
34
|
|
34
35
|
Issue.transaction do
|
35
36
|
@issues.each do |issue|
|
36
|
-
issue
|
37
|
+
# add tags added in placeholder for a single/multiple issue or overwrite tags for single issue
|
38
|
+
params[:append] == 'true' ? issue.tag_list << tags : issue.tag_list = tags
|
37
39
|
issue.save!
|
38
40
|
end
|
39
41
|
end
|
@@ -66,7 +66,11 @@ module AdditionalTagsHelper
|
|
66
66
|
def render_tags_list(tags, **options)
|
67
67
|
return if tags.blank?
|
68
68
|
|
69
|
-
|
69
|
+
options[:show_count] = AdditionalTags.setting? :show_with_count unless options.key? :show_count
|
70
|
+
options[:color_theme] = AdditionalTags.setting :tags_color_theme unless options.key? :color_theme
|
71
|
+
options[:use_colors] = AdditionalTags.use_colors? unless options.key? :use_colors
|
72
|
+
|
73
|
+
style = options.key?(:style) ? options.delete(:style) : AdditionalTags.setting(:tags_sidebar).to_sym
|
70
74
|
tags = tags.all.to_a if tags.respond_to? :all
|
71
75
|
tags = sort_tags_for_list tags
|
72
76
|
|
@@ -94,22 +98,36 @@ module AdditionalTagsHelper
|
|
94
98
|
content_tag(list_el, content, class: 'tags-cloud', style: (style == :simple_cloud ? 'text-align: left;' : ''))
|
95
99
|
end
|
96
100
|
|
97
|
-
def additional_tag_link(tag_object,
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
def additional_tag_link(tag_object,
|
102
|
+
link: nil,
|
103
|
+
link_wiki_tag: false,
|
104
|
+
show_count: false,
|
105
|
+
use_colors: nil,
|
106
|
+
name: nil,
|
107
|
+
color_theme: nil,
|
108
|
+
**options)
|
105
109
|
options[:project] = @project if options[:project].blank? && @project.present?
|
106
|
-
|
110
|
+
if !options.key?(:display_type) && @query && @query.display_type != @query.default_display_type
|
111
|
+
options[:display_type] = @query.display_type
|
112
|
+
end
|
113
|
+
|
114
|
+
use_colors = AdditionalTags.use_colors? if use_colors.nil?
|
115
|
+
color_theme = AdditionalTags.setting :tags_color_theme if color_theme.nil?
|
116
|
+
|
117
|
+
tag_info = AdditionalTag.new name: name.nil? ? tag_object.name : name,
|
118
|
+
disable_grouping: !use_colors,
|
119
|
+
color_theme: color_theme
|
120
|
+
tag_name = [tag_info.tag_name]
|
121
|
+
|
122
|
+
tag_style = "background-color: #{tag_info.tag_bg_color}; color: #{tag_info.tag_fg_color}" if use_colors
|
107
123
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
124
|
+
if tag_info.scoped?
|
125
|
+
tag_name << if show_count
|
126
|
+
tag.span tag_info.group_value, class: 'tag-group-value'
|
127
|
+
else
|
128
|
+
tag.span tag_info.group_value, class: 'tag-group-value tag-group-nocount'
|
129
|
+
end
|
130
|
+
end
|
113
131
|
|
114
132
|
tag_name << tag.span(tag_object.count, class: 'tag-count') if show_count
|
115
133
|
|
@@ -139,20 +157,6 @@ module AdditionalTagsHelper
|
|
139
157
|
tag.span content, **style
|
140
158
|
end
|
141
159
|
|
142
|
-
def additional_tag_color(tag_name)
|
143
|
-
"##{Digest::SHA256.hexdigest(tag_name)[0..5]}"
|
144
|
-
end
|
145
|
-
|
146
|
-
def additional_tag_fg_color(bg_color)
|
147
|
-
# calculate contrast text color according to YIQ method
|
148
|
-
# https://24ways.org/2010/calculating-color-contrast/
|
149
|
-
# https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
150
|
-
r = bg_color[1..2].hex
|
151
|
-
g = bg_color[3..4].hex
|
152
|
-
b = bg_color[5..6].hex
|
153
|
-
(r * 299 + g * 587 + b * 114) >= 128_000 ? 'black' : 'white'
|
154
|
-
end
|
155
|
-
|
156
160
|
# plain list of tags
|
157
161
|
def additional_plain_tag_list(tags, sep: nil)
|
158
162
|
sep ||= "#{Query.additional_csv_separator} "
|
@@ -177,6 +181,10 @@ module AdditionalTagsHelper
|
|
177
181
|
unsorted = options.delete :unsorted
|
178
182
|
tag_list = AdditionalTags::Tags.sort_tag_list tag_list unless unsorted
|
179
183
|
|
184
|
+
# set defaults if not defined
|
185
|
+
options[:use_colors] = AdditionalTags.use_colors? unless options.key? :use_colors
|
186
|
+
options[:color_theme] = AdditionalTags.setting :tags_color_theme unless options.key? :color_theme
|
187
|
+
|
180
188
|
safe_join tag_list.map { |tag| additional_tag_link tag, **options },
|
181
189
|
additional_tag_sep(use_colors: options[:use_colors])
|
182
190
|
end
|
@@ -208,7 +216,7 @@ module AdditionalTagsHelper
|
|
208
216
|
|
209
217
|
private
|
210
218
|
|
211
|
-
def tag_url(tag_name, filter: nil, tag_action: nil, tag_controller: nil, project: nil)
|
219
|
+
def tag_url(tag_name, filter: nil, tag_action: nil, tag_controller: nil, project: nil, display_type: nil)
|
212
220
|
action = tag_action.presence || (controller_name == 'hrm_user_resources' ? 'show' : 'index')
|
213
221
|
|
214
222
|
fields = [:tags]
|
@@ -225,6 +233,7 @@ module AdditionalTagsHelper
|
|
225
233
|
{ controller: tag_controller.presence || controller_name,
|
226
234
|
action: action,
|
227
235
|
set_filter: 1,
|
236
|
+
display_type: display_type,
|
228
237
|
project_id: project,
|
229
238
|
f: fields,
|
230
239
|
v: values,
|
@@ -44,9 +44,7 @@ module AdditionalTagsIssuesHelper
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def render_sidebar_tags
|
47
|
-
options = {
|
48
|
-
filter: AdditionalTags.setting?(:open_issues_only) ? { field: :status_id, operator: 'o' } : nil,
|
49
|
-
style: AdditionalTags.setting(:tags_sidebar).to_sym,
|
47
|
+
options = { filter: AdditionalTags.setting?(:open_issues_only) ? { field: :status_id, operator: 'o' } : nil,
|
50
48
|
project: @project }
|
51
49
|
|
52
50
|
options[:tag_action] = 'show' if %w[gantts calendars].include? controller_name
|
@@ -10,26 +10,32 @@ module AdditionalTagsWikiHelper
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def render_sidebar_tags
|
13
|
-
options = {
|
14
|
-
style: AdditionalTags.setting(:tags_sidebar).to_sym,
|
15
|
-
link_wiki_tag: true,
|
13
|
+
options = { link_wiki_tag: true,
|
16
14
|
project: @project }
|
17
15
|
|
18
16
|
render_tags_list sidebar_tags, **options
|
19
17
|
end
|
20
18
|
|
21
|
-
def render_wiki_index_title(project, tag
|
19
|
+
def render_wiki_index_title(project: nil, name: nil, tag: nil, title: :label_wiki)
|
22
20
|
if tag.present?
|
23
|
-
|
24
|
-
|
21
|
+
tag_object = ActsAsTaggableOn::Tag.new name: tag
|
22
|
+
|
23
|
+
if project
|
24
|
+
safe_join [l(:label_wiki_index_for_tag), additional_tag_link(tag_object, link: '#')], ' '
|
25
|
+
else
|
26
|
+
title = [link_to(l(title), wiki_index_path)]
|
25
27
|
title << Additionals::LIST_SEPARATOR
|
26
|
-
title <<
|
28
|
+
title << l(:label_wiki_index_for_tag)
|
29
|
+
title << additional_tag_link(tag_object, link: '#')
|
27
30
|
safe_join title, ' '
|
28
|
-
else
|
29
|
-
t :label_wiki_index_for_tag_html, tag: tag
|
30
31
|
end
|
32
|
+
elsif name.present?
|
33
|
+
title = [link_to(l(title), wiki_index_path)]
|
34
|
+
title << Additionals::LIST_SEPARATOR
|
35
|
+
title << name
|
36
|
+
safe_join title, ' '
|
31
37
|
else
|
32
|
-
l
|
38
|
+
l title
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
@@ -2,11 +2,16 @@
|
|
2
2
|
|
3
3
|
class AdditionalTagsRemoveUnusedTagJob < AdditionalTagsJob
|
4
4
|
def perform
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
if Rails.env.test?
|
6
|
+
# no cache for testing
|
7
|
+
AdditionalTags::Tags.remove_unused_tags
|
8
|
+
else
|
9
|
+
# only once a minute to reduce load
|
10
|
+
cache = ActiveSupport::Cache::MemoryStore.new expires_in: 1.minute
|
11
|
+
cache.fetch self.class.to_s do
|
12
|
+
AdditionalTags::Tags.remove_unused_tags
|
13
|
+
true
|
14
|
+
end
|
15
|
+
end
|
11
16
|
end
|
12
17
|
end
|