# HG changeset patch # User Daniel Dourvaris # Date 2019-12-02 14:12:39 # Node ID e62fd0874ae0c57ad1375ae520fc3b5400e419e9 # Parent 15b821faef4b69e5b43a21631a886e6d361331d2 issue-tracker: moved example to the input box - removed docs which had bad examples - improved regex for matching newline character properly - added nicer formatting in examples diff --git a/docs/issue-trackers/issue-trackers.rst b/docs/issue-trackers/issue-trackers.rst --- a/docs/issue-trackers/issue-trackers.rst +++ b/docs/issue-trackers/issue-trackers.rst @@ -38,44 +38,39 @@ default one. See the instructions in :re .. _issue-tr-eg-ref: + Jira Integration ---------------- -* Regex = ``(?:^#|\s#)(\w+-\d+)`` -* URL = ``https://myissueserver.com/browse/${id}`` -* Issue Prefix = ``#`` +Please check examples in the view for configuration the issue trackers. + Confluence (Wiki) ----------------- -* Regex = ``(?:conf-)([A-Z0-9]+)`` -* URL = ``https://example.atlassian.net/display/wiki/${id}/${repo_name}`` -* issue prefix = ``CONF-`` +Please check examples in the view for configuration the issue trackers. + Redmine Integration ------------------- -* Regex = ``(issue-+\d+)`` -* URL = ``https://myissueserver.com/redmine/issue/${id}`` -* Issue Prefix = ``issue-`` +Please check examples in the view for configuration the issue trackers. + -Redmine (wiki) --------------- +Redmine wiki Integration +------------------------ -* Regex = ``(?:wiki-)([a-zA-Z0-9]+)`` -* URL = ``https://example.com/redmine/projects/wiki/${repo_name}`` -* Issue prefix = ``Issue-`` +Please check examples in the view for configuration the issue trackers. + Pivotal Tracker --------------- -* Regex = ``(?:pivot-)(?\d+)-(?\d+)`` -* URL = ``https://www.pivotaltracker.com/s/projects/${project_id}/stories/${story}`` -* Issue prefix = ``Piv-`` +Please check examples in the view for configuration the issue trackers. + Trello ------ -* Regex = ``(?:trello-)(?[a-zA-Z0-9]+)`` -* URL = ``https://trello.com/example.com/${card_id}`` -* Issue prefix = ``Trello-`` +Please check examples in the view for configuration the issue trackers. + diff --git a/rhodecode/apps/admin/tests/test_admin_settings.py b/rhodecode/apps/admin/tests/test_admin_settings.py --- a/rhodecode/apps/admin/tests/test_admin_settings.py +++ b/rhodecode/apps/admin/tests/test_admin_settings.py @@ -726,7 +726,7 @@ class TestAdminSettingsIssueTracker(obje IssueTrackerSettingsModel().delete_entries(self.uid) def test_delete_issuetracker_pattern( - self, autologin_user, backend, csrf_token, settings_util): + self, autologin_user, backend, csrf_token, settings_util, xhr_header): pattern = 'issuetracker_pat' uid = md5(pattern) settings_util.create_rhodecode_setting( @@ -737,6 +737,6 @@ class TestAdminSettingsIssueTracker(obje 'uid': uid, 'csrf_token': csrf_token } - self.app.post(post_url, post_data, status=302) + self.app.post(post_url, post_data, extra_environ=xhr_header, status=200) settings = SettingsModel().get_all_settings() assert 'rhodecode_%s%s' % (self.SHORT_PATTERN_KEY, uid) not in settings diff --git a/rhodecode/apps/admin/views/settings.py b/rhodecode/apps/admin/views/settings.py --- a/rhodecode/apps/admin/views/settings.py +++ b/rhodecode/apps/admin/views/settings.py @@ -518,7 +518,7 @@ class AdminSettingsView(BaseAppView): @CSRFRequired() @view_config( route_name='admin_settings_issuetracker_delete', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + renderer='json_ext', xhr=True) def settings_issuetracker_delete(self): _ = self.request.translate self.load_default_context() @@ -528,8 +528,11 @@ class AdminSettingsView(BaseAppView): except Exception: log.exception('Failed to delete issue tracker setting %s', uid) raise HTTPNotFound() - h.flash(_('Removed issue tracker entry'), category='success') - raise HTTPFound(h.route_path('admin_settings_issuetracker')) + + SettingsModel().invalidate_settings_cache() + h.flash(_('Removed issue tracker entry.'), category='success') + + return {'deleted': uid} @LoginRequired() @HasPermissionAllDecorator('hg.admin') diff --git a/rhodecode/apps/repository/tests/test_repo_issue_tracker.py b/rhodecode/apps/repository/tests/test_repo_issue_tracker.py --- a/rhodecode/apps/repository/tests/test_repo_issue_tracker.py +++ b/rhodecode/apps/repository/tests/test_repo_issue_tracker.py @@ -125,7 +125,7 @@ class TestRepoIssueTracker(object): self.settings_model.delete_entries(self.uid) def test_delete_issuetracker_pattern( - self, autologin_user, backend, csrf_token, settings_util): + self, autologin_user, backend, csrf_token, settings_util, xhr_header): repo = backend.create_repo() repo_name = repo.repo_name entry_key = 'issuetracker_pat_' @@ -141,8 +141,9 @@ class TestRepoIssueTracker(object): repo_name=backend.repo.repo_name), { 'uid': uid, - 'csrf_token': csrf_token - }, status=302) + 'csrf_token': csrf_token, + '': '' + }, extra_environ=xhr_header, status=200) settings = IssueTrackerSettingsModel( repo=Repository.get_by_repo_name(repo_name)).get_repo_settings() assert 'rhodecode_%s%s' % (entry_key, uid) not in settings diff --git a/rhodecode/apps/repository/views/repo_settings_issue_trackers.py b/rhodecode/apps/repository/views/repo_settings_issue_trackers.py --- a/rhodecode/apps/repository/views/repo_settings_issue_trackers.py +++ b/rhodecode/apps/repository/views/repo_settings_issue_trackers.py @@ -20,7 +20,7 @@ import logging -from pyramid.httpexceptions import HTTPFound +from pyramid.httpexceptions import HTTPFound, HTTPNotFound from pyramid.view import view_config import formencode @@ -31,7 +31,7 @@ from rhodecode.lib.auth import ( LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) from rhodecode.model.forms import IssueTrackerPatternsForm from rhodecode.model.meta import Session -from rhodecode.model.settings import IssueTrackerSettingsModel +from rhodecode.model.settings import IssueTrackerSettingsModel, SettingsModel log = logging.getLogger(__name__) @@ -64,7 +64,7 @@ class RepoSettingsIssueTrackersView(Repo @CSRFRequired() @view_config( route_name='edit_repo_issuetracker_test', request_method='POST', - xhr=True, renderer='string') + renderer='string', xhr=True) def repo_issuetracker_test(self): return h.urlify_commit_message( self.request.POST.get('test_text', ''), @@ -75,7 +75,7 @@ class RepoSettingsIssueTrackersView(Repo @CSRFRequired() @view_config( route_name='edit_repo_issuetracker_delete', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + renderer='json_ext', xhr=True) def repo_issuetracker_delete(self): _ = self.request.translate uid = self.request.POST.get('uid') @@ -85,10 +85,12 @@ class RepoSettingsIssueTrackersView(Repo except Exception: h.flash(_('Error occurred during deleting issue tracker entry'), category='error') - else: - h.flash(_('Removed issue tracker entry'), category='success') - raise HTTPFound( - h.route_path('edit_repo_issuetracker', repo_name=self.db_repo_name)) + raise HTTPNotFound() + + SettingsModel().invalidate_settings_cache() + h.flash(_('Removed issue tracker entry.'), category='success') + + return {'deleted': uid} def _update_patterns(self, form, repo_settings): for uid in form['delete_patterns']: diff --git a/rhodecode/public/css/tables.less b/rhodecode/public/css/tables.less --- a/rhodecode/public/css/tables.less +++ b/rhodecode/public/css/tables.less @@ -191,6 +191,24 @@ table.dataTable { padding-left: .65em; } + &.td-issue-tracker-name { + width: 180px; + input { + width: 180px; + } + + } + + &.td-issue-tracker-regex { + white-space: nowrap; + + min-width: 300px; + input { + min-width: 300px; + } + + } + &.td-url { white-space: nowrap; } diff --git a/rhodecode/templates/base/issue_tracker_settings.mako b/rhodecode/templates/base/issue_tracker_settings.mako --- a/rhodecode/templates/base/issue_tracker_settings.mako +++ b/rhodecode/templates/base/issue_tracker_settings.mako @@ -5,24 +5,101 @@ ## ${its.issue_tracker_settings_test(test_url)} <%def name="issue_tracker_settings_table(patterns, form_url, delete_url)"> +<% +# Name/desc, pattern, issue prefix +examples = [ + ( + ' ', + ' ', + ' ', + ' ' + ), + + ( + 'Redmine', + '(^#|\s#)(?P\d+)', + 'https://myissueserver.com/${repo}/issue/${issue_id}', + '' + ), + + ( + 'Redmine - Alternative', + '(?:issue-)(\d+)', + 'https://myissueserver.com/redmine/issue/${id}', + '' + ), + + ( + 'Redmine - Wiki', + '(?:wiki-)([a-zA-Z0-9]+)', + 'http://example.org/projects/${repo_name}/wiki/${id}', + 'wiki-' + ), + + ( + 'JIRA - All tickets', + '(^|\s\w+-\d+)', + 'https://myjira.com/browse/${id}', + '' + ), + + ( + 'JIRA - Project (JRA)', + '(?:(^|\s)(?P(?:JRA-|JRA-)(?:\d+)))', + 'https://myjira.com/${issue_id}', + '' + ), + + ( + 'Confluence WIKI', + '(?:conf-)([A-Z0-9]+)', + 'https://example.atlassian.net/display/wiki/${id}/${repo_name}', + 'CONF-', + ), + + ( + 'Pivotal Tracker', + '(?:pivot-)(?\d+)-(?\d+)', + 'https://www.pivotaltracker.com/s/projects/${project_id}/stories/${story}', + 'PIV-', + ), + + ( + 'Trello', + '(?:trello-)(?[a-zA-Z0-9]+)', + 'https://trello.com/example.com/${card_id}', + 'TRELLO-', + ), +] +%> + - + - - - - - - - + % for name, pat, url, pref in examples: + + + + + + + + % endfor + %for uid, entry in patterns: - -
${_('Description')} ${_('Pattern')} ${_('Url')}${_('Prefix')}${_('Extra Prefix')}
Example${'(?:#)(?P\d+)'}${'https://myissueserver.com/${repo}/issue/${issue_id}'}#${_('Read more')}
${name}${pat}${url}${pref} + % if loop.index == 0: + ${_('show examples')} + % else: + copy to input + % endif +
+ ${entry.desc} @@ -30,7 +107,7 @@ ${h.text('new_pattern_description_'+uid, class_='medium-inline', value=entry.desc or '')} + ${entry.pat} @@ -95,13 +172,13 @@ if (confirm("${_('Confirm to remove this pattern:')} "+$(entry).data('desc'))) { $.ajax({ type: "POST", - url: "${delete_url}", + url: "${delete_url}", data: { 'csrf_token': CSRF_TOKEN, 'uid':$(entry).data('uid') }, success: function(){ - location.reload(); + window.location.reload(); }, error: function(data, textStatus, errorThrown){ alert("Error while deleting entry.\nError code {0} ({1}). URL: {2}".format(data.status,data.statusText,$(entry)[0].url)); @@ -137,6 +214,24 @@ $('#add_pattern').on('click', function(e) { addNewPatternInput(); }); + + var copied = false; + copyToInput = function (elem, name, pat, url, pref) { + if (copied === false) { + addNewPatternInput(); + copied = true; + } + $(elem).hide(); + var load = function(text){ + return text.replace(/["]/g, "") + }; + $('#description_1').val(load(name)); + $('#pattern_1').val(load(pat)); + $('#url_1').val(load(url)); + $('#prefix_1').val(load(pref)); + + } + @@ -144,12 +239,12 @@ - -