Show More
@@ -38,44 +38,39 b' default one. See the instructions in :re' | |||
|
38 | 38 | |
|
39 | 39 | .. _issue-tr-eg-ref: |
|
40 | 40 | |
|
41 | ||
|
41 | 42 | Jira Integration |
|
42 | 43 | ---------------- |
|
43 | 44 | |
|
44 | * Regex = ``(?:^#|\s#)(\w+-\d+)`` | |
|
45 | * URL = ``https://myissueserver.com/browse/${id}`` | |
|
46 | * Issue Prefix = ``#`` | |
|
45 | Please check examples in the view for configuration the issue trackers. | |
|
46 | ||
|
47 | 47 | |
|
48 | 48 | Confluence (Wiki) |
|
49 | 49 | ----------------- |
|
50 | 50 | |
|
51 | * Regex = ``(?:conf-)([A-Z0-9]+)`` | |
|
52 | * URL = ``https://example.atlassian.net/display/wiki/${id}/${repo_name}`` | |
|
53 | * issue prefix = ``CONF-`` | |
|
51 | Please check examples in the view for configuration the issue trackers. | |
|
52 | ||
|
54 | 53 | |
|
55 | 54 | Redmine Integration |
|
56 | 55 | ------------------- |
|
57 | 56 | |
|
58 | * Regex = ``(issue-+\d+)`` | |
|
59 | * URL = ``https://myissueserver.com/redmine/issue/${id}`` | |
|
60 | * Issue Prefix = ``issue-`` | |
|
57 | Please check examples in the view for configuration the issue trackers. | |
|
58 | ||
|
61 | 59 | |
|
62 |
Redmine |
|
|
63 | -------------- | |
|
60 | Redmine wiki Integration | |
|
61 | ------------------------ | |
|
64 | 62 | |
|
65 | * Regex = ``(?:wiki-)([a-zA-Z0-9]+)`` | |
|
66 | * URL = ``https://example.com/redmine/projects/wiki/${repo_name}`` | |
|
67 | * Issue prefix = ``Issue-`` | |
|
63 | Please check examples in the view for configuration the issue trackers. | |
|
64 | ||
|
68 | 65 | |
|
69 | 66 | Pivotal Tracker |
|
70 | 67 | --------------- |
|
71 | 68 | |
|
72 | * Regex = ``(?:pivot-)(?<project_id>\d+)-(?<story>\d+)`` | |
|
73 | * URL = ``https://www.pivotaltracker.com/s/projects/${project_id}/stories/${story}`` | |
|
74 | * Issue prefix = ``Piv-`` | |
|
69 | Please check examples in the view for configuration the issue trackers. | |
|
70 | ||
|
75 | 71 | |
|
76 | 72 | Trello |
|
77 | 73 | ------ |
|
78 | 74 | |
|
79 | * Regex = ``(?:trello-)(?<card_id>[a-zA-Z0-9]+)`` | |
|
80 | * URL = ``https://trello.com/example.com/${card_id}`` | |
|
81 | * Issue prefix = ``Trello-`` | |
|
75 | Please check examples in the view for configuration the issue trackers. | |
|
76 |
@@ -726,7 +726,7 b' class TestAdminSettingsIssueTracker(obje' | |||
|
726 | 726 | IssueTrackerSettingsModel().delete_entries(self.uid) |
|
727 | 727 | |
|
728 | 728 | def test_delete_issuetracker_pattern( |
|
729 | self, autologin_user, backend, csrf_token, settings_util): | |
|
729 | self, autologin_user, backend, csrf_token, settings_util, xhr_header): | |
|
730 | 730 | pattern = 'issuetracker_pat' |
|
731 | 731 | uid = md5(pattern) |
|
732 | 732 | settings_util.create_rhodecode_setting( |
@@ -737,6 +737,6 b' class TestAdminSettingsIssueTracker(obje' | |||
|
737 | 737 | 'uid': uid, |
|
738 | 738 | 'csrf_token': csrf_token |
|
739 | 739 | } |
|
740 |
self.app.post(post_url, post_data, status= |
|
|
740 | self.app.post(post_url, post_data, extra_environ=xhr_header, status=200) | |
|
741 | 741 | settings = SettingsModel().get_all_settings() |
|
742 | 742 | assert 'rhodecode_%s%s' % (self.SHORT_PATTERN_KEY, uid) not in settings |
@@ -518,7 +518,7 b' class AdminSettingsView(BaseAppView):' | |||
|
518 | 518 | @CSRFRequired() |
|
519 | 519 | @view_config( |
|
520 | 520 | route_name='admin_settings_issuetracker_delete', request_method='POST', |
|
521 | renderer='rhodecode:templates/admin/settings/settings.mako') | |
|
521 | renderer='json_ext', xhr=True) | |
|
522 | 522 | def settings_issuetracker_delete(self): |
|
523 | 523 | _ = self.request.translate |
|
524 | 524 | self.load_default_context() |
@@ -528,8 +528,11 b' class AdminSettingsView(BaseAppView):' | |||
|
528 | 528 | except Exception: |
|
529 | 529 | log.exception('Failed to delete issue tracker setting %s', uid) |
|
530 | 530 | raise HTTPNotFound() |
|
531 | h.flash(_('Removed issue tracker entry'), category='success') | |
|
532 | raise HTTPFound(h.route_path('admin_settings_issuetracker')) | |
|
531 | ||
|
532 | SettingsModel().invalidate_settings_cache() | |
|
533 | h.flash(_('Removed issue tracker entry.'), category='success') | |
|
534 | ||
|
535 | return {'deleted': uid} | |
|
533 | 536 | |
|
534 | 537 | @LoginRequired() |
|
535 | 538 | @HasPermissionAllDecorator('hg.admin') |
@@ -125,7 +125,7 b' class TestRepoIssueTracker(object):' | |||
|
125 | 125 | self.settings_model.delete_entries(self.uid) |
|
126 | 126 | |
|
127 | 127 | def test_delete_issuetracker_pattern( |
|
128 | self, autologin_user, backend, csrf_token, settings_util): | |
|
128 | self, autologin_user, backend, csrf_token, settings_util, xhr_header): | |
|
129 | 129 | repo = backend.create_repo() |
|
130 | 130 | repo_name = repo.repo_name |
|
131 | 131 | entry_key = 'issuetracker_pat_' |
@@ -141,8 +141,9 b' class TestRepoIssueTracker(object):' | |||
|
141 | 141 | repo_name=backend.repo.repo_name), |
|
142 | 142 | { |
|
143 | 143 | 'uid': uid, |
|
144 | 'csrf_token': csrf_token | |
|
145 | }, status=302) | |
|
144 | 'csrf_token': csrf_token, | |
|
145 | '': '' | |
|
146 | }, extra_environ=xhr_header, status=200) | |
|
146 | 147 | settings = IssueTrackerSettingsModel( |
|
147 | 148 | repo=Repository.get_by_repo_name(repo_name)).get_repo_settings() |
|
148 | 149 | assert 'rhodecode_%s%s' % (entry_key, uid) not in settings |
@@ -20,7 +20,7 b'' | |||
|
20 | 20 | |
|
21 | 21 | import logging |
|
22 | 22 | |
|
23 | from pyramid.httpexceptions import HTTPFound | |
|
23 | from pyramid.httpexceptions import HTTPFound, HTTPNotFound | |
|
24 | 24 | from pyramid.view import view_config |
|
25 | 25 | import formencode |
|
26 | 26 | |
@@ -31,7 +31,7 b' from rhodecode.lib.auth import (' | |||
|
31 | 31 | LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) |
|
32 | 32 | from rhodecode.model.forms import IssueTrackerPatternsForm |
|
33 | 33 | from rhodecode.model.meta import Session |
|
34 | from rhodecode.model.settings import IssueTrackerSettingsModel | |
|
34 | from rhodecode.model.settings import IssueTrackerSettingsModel, SettingsModel | |
|
35 | 35 | |
|
36 | 36 | log = logging.getLogger(__name__) |
|
37 | 37 | |
@@ -64,7 +64,7 b' class RepoSettingsIssueTrackersView(Repo' | |||
|
64 | 64 | @CSRFRequired() |
|
65 | 65 | @view_config( |
|
66 | 66 | route_name='edit_repo_issuetracker_test', request_method='POST', |
|
67 |
|
|
|
67 | renderer='string', xhr=True) | |
|
68 | 68 | def repo_issuetracker_test(self): |
|
69 | 69 | return h.urlify_commit_message( |
|
70 | 70 | self.request.POST.get('test_text', ''), |
@@ -75,7 +75,7 b' class RepoSettingsIssueTrackersView(Repo' | |||
|
75 | 75 | @CSRFRequired() |
|
76 | 76 | @view_config( |
|
77 | 77 | route_name='edit_repo_issuetracker_delete', request_method='POST', |
|
78 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') | |
|
78 | renderer='json_ext', xhr=True) | |
|
79 | 79 | def repo_issuetracker_delete(self): |
|
80 | 80 | _ = self.request.translate |
|
81 | 81 | uid = self.request.POST.get('uid') |
@@ -85,10 +85,12 b' class RepoSettingsIssueTrackersView(Repo' | |||
|
85 | 85 | except Exception: |
|
86 | 86 | h.flash(_('Error occurred during deleting issue tracker entry'), |
|
87 | 87 | category='error') |
|
88 | else: | |
|
89 | h.flash(_('Removed issue tracker entry'), category='success') | |
|
90 | raise HTTPFound( | |
|
91 | h.route_path('edit_repo_issuetracker', repo_name=self.db_repo_name)) | |
|
88 | raise HTTPNotFound() | |
|
89 | ||
|
90 | SettingsModel().invalidate_settings_cache() | |
|
91 | h.flash(_('Removed issue tracker entry.'), category='success') | |
|
92 | ||
|
93 | return {'deleted': uid} | |
|
92 | 94 | |
|
93 | 95 | def _update_patterns(self, form, repo_settings): |
|
94 | 96 | for uid in form['delete_patterns']: |
@@ -191,6 +191,24 b' table.dataTable {' | |||
|
191 | 191 | padding-left: .65em; |
|
192 | 192 | } |
|
193 | 193 | |
|
194 | &.td-issue-tracker-name { | |
|
195 | width: 180px; | |
|
196 | input { | |
|
197 | width: 180px; | |
|
198 | } | |
|
199 | ||
|
200 | } | |
|
201 | ||
|
202 | &.td-issue-tracker-regex { | |
|
203 | white-space: nowrap; | |
|
204 | ||
|
205 | min-width: 300px; | |
|
206 | input { | |
|
207 | min-width: 300px; | |
|
208 | } | |
|
209 | ||
|
210 | } | |
|
211 | ||
|
194 | 212 | &.td-url { |
|
195 | 213 | white-space: nowrap; |
|
196 | 214 | } |
@@ -5,24 +5,101 b'' | |||
|
5 | 5 | ## ${its.issue_tracker_settings_test(test_url)} |
|
6 | 6 | |
|
7 | 7 | <%def name="issue_tracker_settings_table(patterns, form_url, delete_url)"> |
|
8 | <% | |
|
9 | # Name/desc, pattern, issue prefix | |
|
10 | examples = [ | |
|
11 | ( | |
|
12 | ' ', | |
|
13 | ' ', | |
|
14 | ' ', | |
|
15 | ' ' | |
|
16 | ), | |
|
17 | ||
|
18 | ( | |
|
19 | 'Redmine', | |
|
20 | '(^#|\s#)(?P<issue_id>\d+)', | |
|
21 | 'https://myissueserver.com/${repo}/issue/${issue_id}', | |
|
22 | '' | |
|
23 | ), | |
|
24 | ||
|
25 | ( | |
|
26 | 'Redmine - Alternative', | |
|
27 | '(?:issue-)(\d+)', | |
|
28 | 'https://myissueserver.com/redmine/issue/${id}', | |
|
29 | '' | |
|
30 | ), | |
|
31 | ||
|
32 | ( | |
|
33 | 'Redmine - Wiki', | |
|
34 | '(?:wiki-)([a-zA-Z0-9]+)', | |
|
35 | 'http://example.org/projects/${repo_name}/wiki/${id}', | |
|
36 | 'wiki-' | |
|
37 | ), | |
|
38 | ||
|
39 | ( | |
|
40 | 'JIRA - All tickets', | |
|
41 | '(^|\s\w+-\d+)', | |
|
42 | 'https://myjira.com/browse/${id}', | |
|
43 | '' | |
|
44 | ), | |
|
45 | ||
|
46 | ( | |
|
47 | 'JIRA - Project (JRA)', | |
|
48 | '(?:(^|\s)(?P<issue_id>(?:JRA-|JRA-)(?:\d+)))', | |
|
49 | 'https://myjira.com/${issue_id}', | |
|
50 | '' | |
|
51 | ), | |
|
52 | ||
|
53 | ( | |
|
54 | 'Confluence WIKI', | |
|
55 | '(?:conf-)([A-Z0-9]+)', | |
|
56 | 'https://example.atlassian.net/display/wiki/${id}/${repo_name}', | |
|
57 | 'CONF-', | |
|
58 | ), | |
|
59 | ||
|
60 | ( | |
|
61 | 'Pivotal Tracker', | |
|
62 | '(?:pivot-)(?<project_id>\d+)-(?<story>\d+)', | |
|
63 | 'https://www.pivotaltracker.com/s/projects/${project_id}/stories/${story}', | |
|
64 | 'PIV-', | |
|
65 | ), | |
|
66 | ||
|
67 | ( | |
|
68 | 'Trello', | |
|
69 | '(?:trello-)(?<card_id>[a-zA-Z0-9]+)', | |
|
70 | 'https://trello.com/example.com/${card_id}', | |
|
71 | 'TRELLO-', | |
|
72 | ), | |
|
73 | ] | |
|
74 | %> | |
|
75 | ||
|
8 | 76 | <table class="rctable issuetracker"> |
|
9 | 77 | <tr> |
|
10 | 78 | <th>${_('Description')}</th> |
|
11 | 79 | <th>${_('Pattern')}</th> |
|
12 | 80 | <th>${_('Url')}</th> |
|
13 | <th>${_('Prefix')}</th> | |
|
81 | <th>${_('Extra Prefix')}</th> | |
|
14 | 82 | <th ></th> |
|
15 | 83 | </tr> |
|
16 | <tr> | |
|
17 | <td class="td-description issue-tracker-example">Example</td> | |
|
18 |
<td class="td- |
|
|
19 |
<td class="td- |
|
|
20 |
<td class="td- |
|
|
21 | <td class="issue-tracker-example"><a href="${h.route_url('enterprise_issue_tracker_settings')}" target="_blank">${_('Read more')}</a></td> | |
|
22 |
< |
|
|
84 | % for name, pat, url, pref in examples: | |
|
85 | <tr class="it-examples" style="${'' if loop.index == 0 else 'display:none'}"> | |
|
86 | <td class="td-issue-tracker-name issue-tracker-example">${name}</td> | |
|
87 | <td class="td-regex issue-tracker-example">${pat}</td> | |
|
88 | <td class="td-url issue-tracker-example">${url}</td> | |
|
89 | <td class="td-prefix issue-tracker-example">${pref}</td> | |
|
90 | <td> | |
|
91 | % if loop.index == 0: | |
|
92 | <a href="#showMore" onclick="$('.it-examples').toggle(); return false">${_('show examples')}</a> | |
|
93 | % else: | |
|
94 | <a href="#copyToInput" onclick="copyToInput(this, '${h.json.dumps(name)}', '${h.json.dumps(pat)}', '${h.json.dumps(url)}', '${h.json.dumps(pref)}'); return false">copy to input</a> | |
|
95 | % endif | |
|
96 | </td> | |
|
97 | </tr> | |
|
98 | % endfor | |
|
99 | ||
|
23 | 100 |
|
|
24 | 101 | <tr id="entry_${uid}"> |
|
25 |
<td class="td- |
|
|
102 | <td class="td-issue-tracker-name issuetracker_desc"> | |
|
26 | 103 | <span class="entry"> |
|
27 | 104 | ${entry.desc} |
|
28 | 105 | </span> |
@@ -30,7 +107,7 b'' | |||
|
30 | 107 | ${h.text('new_pattern_description_'+uid, class_='medium-inline', value=entry.desc or '')} |
|
31 | 108 | </span> |
|
32 | 109 | </td> |
|
33 | <td class="td-regex issuetracker_pat"> | |
|
110 | <td class="td-issue-tracker-regex issuetracker_pat"> | |
|
34 | 111 | <span class="entry"> |
|
35 | 112 | ${entry.pat} |
|
36 | 113 | </span> |
@@ -95,13 +172,13 b'' | |||
|
95 | 172 | if (confirm("${_('Confirm to remove this pattern:')} "+$(entry).data('desc'))) { |
|
96 | 173 | $.ajax({ |
|
97 | 174 | type: "POST", |
|
98 |
url: "${delete_url}", |
|
|
175 | url: "${delete_url}", | |
|
99 | 176 | data: { |
|
100 | 177 | 'csrf_token': CSRF_TOKEN, |
|
101 | 178 | 'uid':$(entry).data('uid') |
|
102 | 179 | }, |
|
103 | 180 | success: function(){ |
|
104 | location.reload(); | |
|
181 | window.location.reload(); | |
|
105 | 182 | }, |
|
106 | 183 | error: function(data, textStatus, errorThrown){ |
|
107 | 184 | alert("Error while deleting entry.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(entry)[0].url)); |
@@ -137,6 +214,24 b'' | |||
|
137 | 214 | $('#add_pattern').on('click', function(e) { |
|
138 | 215 | addNewPatternInput(); |
|
139 | 216 | }); |
|
217 | ||
|
218 | var copied = false; | |
|
219 | copyToInput = function (elem, name, pat, url, pref) { | |
|
220 | if (copied === false) { | |
|
221 | addNewPatternInput(); | |
|
222 | copied = true; | |
|
223 | } | |
|
224 | $(elem).hide(); | |
|
225 | var load = function(text){ | |
|
226 | return text.replace(/["]/g, "") | |
|
227 | }; | |
|
228 | $('#description_1').val(load(name)); | |
|
229 | $('#pattern_1').val(load(pat)); | |
|
230 | $('#url_1').val(load(url)); | |
|
231 | $('#prefix_1').val(load(pref)); | |
|
232 | ||
|
233 | } | |
|
234 | ||
|
140 | 235 | </script> |
|
141 | 236 | </%def> |
|
142 | 237 | |
@@ -144,12 +239,12 b'' | |||
|
144 | 239 | <table id="add-row-tmpl" style="display: none;"> |
|
145 | 240 | <tbody> |
|
146 | 241 | <tr class="new_pattern"> |
|
147 |
<td class="td- |
|
|
242 | <td class="td-issue-tracker-name issuetracker_desc"> | |
|
148 | 243 | <span class="entry"> |
|
149 |
|
|
|
244 | <input class="medium-inline" id="description_##UUID##" name="new_pattern_description_##UUID##" value="##DESCRIPTION##" type="text"> | |
|
150 | 245 | </span> |
|
151 | 246 | </td> |
|
152 | <td class="td-regex issuetracker_pat"> | |
|
247 | <td class="td-issue-tracker-regex issuetracker_pat"> | |
|
153 | 248 | <span class="entry"> |
|
154 | 249 | <input class="medium-inline" id="pattern_##UUID##" name="new_pattern_pattern_##UUID##" placeholder="Pattern" |
|
155 | 250 | value="##PATTERN##" type="text"> |
@@ -178,9 +273,14 b'' | |||
|
178 | 273 | <div class="fields"> |
|
179 | 274 | <div class="field"> |
|
180 | 275 | <div class='textarea-full'> |
|
181 |
<textarea id="test_pattern_data" rows="1 |
|
|
276 | <textarea id="test_pattern_data" rows="12"> | |
|
182 | 277 | This is an example text for testing issue tracker patterns. |
|
183 | This commit fixes ticket #451. | |
|
278 | This commit fixes ticket #451 and ticket #910. | |
|
279 | Following tickets will get mentioned: | |
|
280 | #123 | |
|
281 | #456 | |
|
282 | JRA-123 | |
|
283 | JRA-456 | |
|
184 | 284 | Open a pull request !101 to contribute ! |
|
185 | 285 | Added tag v1.3.0 for commit 0f3b629be725 |
|
186 | 286 |
General Comments 0
You need to be logged in to leave comments.
Login now