diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py
--- a/rhodecode/apps/_base/__init__.py
+++ b/rhodecode/apps/_base/__init__.py
@@ -268,6 +268,34 @@ class RepoRoutePredicate(object):
return False
+class RepoTypeRoutePredicate(object):
+ def __init__(self, val, config):
+ self.val = val or ['hg', 'git', 'svn']
+
+ def text(self):
+ return 'repo_accepted_type = %s' % self.val
+
+ phash = text
+
+ def __call__(self, info, request):
+
+ rhodecode_db_repo = request.db_repo
+
+ log.debug(
+ '%s checking repo type for %s in %s',
+ self.__class__.__name__, rhodecode_db_repo.repo_type, self.val)
+
+ if rhodecode_db_repo.repo_type in self.val:
+ return True
+ else:
+ log.warning('Current view is not supported for repo type:%s',
+ rhodecode_db_repo.repo_type)
+ return False
+
+
+
def includeme(config):
config.add_route_predicate(
'repo_route', RepoRoutePredicate)
+ config.add_route_predicate(
+ 'repo_accepted_types', RepoTypeRoutePredicate)
\ No newline at end of file
diff --git a/rhodecode/apps/repository/__init__.py b/rhodecode/apps/repository/__init__.py
--- a/rhodecode/apps/repository/__init__.py
+++ b/rhodecode/apps/repository/__init__.py
@@ -47,6 +47,16 @@ def includeme(config):
pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id}',
repo_route=True)
+ config.add_route(
+ name='pullrequest_show_all',
+ pattern='/{repo_name:.*?[^/]}/pull-request',
+ repo_route=True, repo_accepted_types=['hg', 'git'])
+
+ config.add_route(
+ name='pullrequest_show_all_data',
+ pattern='/{repo_name:.*?[^/]}/pull-request-data',
+ repo_route=True, repo_accepted_types=['hg', 'git'])
+
# Settings
config.add_route(
name='edit_repo',
diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/apps/repository/views/repo_pull_requests.py
@@ -0,0 +1,184 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2011-2017 RhodeCode GmbH
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License, version 3
+# (only), as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+# This program is dual-licensed. If you wish to learn more about the
+# RhodeCode Enterprise Edition, including its added features, Support services,
+# and proprietary license terms, please see https://rhodecode.com/licenses/
+
+import logging
+
+from pyramid.view import view_config
+
+from rhodecode.apps._base import RepoAppView, DataGridAppView
+from rhodecode.lib import helpers as h
+from rhodecode.lib import audit_logger
+from rhodecode.lib.auth import (
+ LoginRequired, HasRepoPermissionAnyDecorator)
+from rhodecode.lib.utils import PartialRenderer
+from rhodecode.lib.utils2 import str2bool
+from rhodecode.model.comment import CommentsModel
+from rhodecode.model.db import PullRequest
+from rhodecode.model.pull_request import PullRequestModel
+
+log = logging.getLogger(__name__)
+
+
+class RepoPullRequestsView(RepoAppView, DataGridAppView):
+
+ def load_default_context(self):
+ c = self._get_local_tmpl_context()
+
+ # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
+ c.repo_info = self.db_repo
+
+ self._register_global_c(c)
+ return c
+
+ def _get_pull_requests_list(
+ self, repo_name, source, filter_type, opened_by, statuses):
+
+ draw, start, limit = self._extract_chunk(self.request)
+ search_q, order_by, order_dir = self._extract_ordering(self.request)
+ _render = PartialRenderer('data_table/_dt_elements.mako')
+
+ # pagination
+
+ if filter_type == 'awaiting_review':
+ pull_requests = PullRequestModel().get_awaiting_review(
+ repo_name, source=source, opened_by=opened_by,
+ statuses=statuses, offset=start, length=limit,
+ order_by=order_by, order_dir=order_dir)
+ pull_requests_total_count = PullRequestModel().count_awaiting_review(
+ repo_name, source=source, statuses=statuses,
+ opened_by=opened_by)
+ elif filter_type == 'awaiting_my_review':
+ pull_requests = PullRequestModel().get_awaiting_my_review(
+ repo_name, source=source, opened_by=opened_by,
+ user_id=self._rhodecode_user.user_id, statuses=statuses,
+ offset=start, length=limit, order_by=order_by,
+ order_dir=order_dir)
+ pull_requests_total_count = PullRequestModel().count_awaiting_my_review(
+ repo_name, source=source, user_id=self._rhodecode_user.user_id,
+ statuses=statuses, opened_by=opened_by)
+ else:
+ pull_requests = PullRequestModel().get_all(
+ repo_name, source=source, opened_by=opened_by,
+ statuses=statuses, offset=start, length=limit,
+ order_by=order_by, order_dir=order_dir)
+ pull_requests_total_count = PullRequestModel().count_all(
+ repo_name, source=source, statuses=statuses,
+ opened_by=opened_by)
+
+ data = []
+ comments_model = CommentsModel()
+ for pr in pull_requests:
+ comments = comments_model.get_all_comments(
+ self.db_repo.repo_id, pull_request=pr)
+
+ data.append({
+ 'name': _render('pullrequest_name',
+ pr.pull_request_id, pr.target_repo.repo_name),
+ 'name_raw': pr.pull_request_id,
+ 'status': _render('pullrequest_status',
+ pr.calculated_review_status()),
+ 'title': _render(
+ 'pullrequest_title', pr.title, pr.description),
+ 'description': h.escape(pr.description),
+ 'updated_on': _render('pullrequest_updated_on',
+ h.datetime_to_time(pr.updated_on)),
+ 'updated_on_raw': h.datetime_to_time(pr.updated_on),
+ 'created_on': _render('pullrequest_updated_on',
+ h.datetime_to_time(pr.created_on)),
+ 'created_on_raw': h.datetime_to_time(pr.created_on),
+ 'author': _render('pullrequest_author',
+ pr.author.full_contact, ),
+ 'author_raw': pr.author.full_name,
+ 'comments': _render('pullrequest_comments', len(comments)),
+ 'comments_raw': len(comments),
+ 'closed': pr.is_closed(),
+ })
+
+ data = ({
+ 'draw': draw,
+ 'data': data,
+ 'recordsTotal': pull_requests_total_count,
+ 'recordsFiltered': pull_requests_total_count,
+ })
+ return data
+
+ @LoginRequired()
+ @HasRepoPermissionAnyDecorator(
+ 'repository.read', 'repository.write', 'repository.admin')
+ @view_config(
+ route_name='pullrequest_show_all', request_method='GET',
+ renderer='rhodecode:templates/pullrequests/pullrequests.mako')
+ def pull_request_list(self):
+ c = self.load_default_context()
+
+ req_get = self.request.GET
+ c.source = str2bool(req_get.get('source'))
+ c.closed = str2bool(req_get.get('closed'))
+ c.my = str2bool(req_get.get('my'))
+ c.awaiting_review = str2bool(req_get.get('awaiting_review'))
+ c.awaiting_my_review = str2bool(req_get.get('awaiting_my_review'))
+
+ c.active = 'open'
+ if c.my:
+ c.active = 'my'
+ if c.closed:
+ c.active = 'closed'
+ if c.awaiting_review and not c.source:
+ c.active = 'awaiting'
+ if c.source and not c.awaiting_review:
+ c.active = 'source'
+ if c.awaiting_my_review:
+ c.active = 'awaiting_my'
+
+ return self._get_template_context(c)
+
+ @LoginRequired()
+ @HasRepoPermissionAnyDecorator(
+ 'repository.read', 'repository.write', 'repository.admin')
+ @view_config(
+ route_name='pullrequest_show_all_data', request_method='GET',
+ renderer='json_ext', xhr=True)
+ def pull_request_list_data(self):
+
+ # additional filters
+ req_get = self.request.GET
+ source = str2bool(req_get.get('source'))
+ closed = str2bool(req_get.get('closed'))
+ my = str2bool(req_get.get('my'))
+ awaiting_review = str2bool(req_get.get('awaiting_review'))
+ awaiting_my_review = str2bool(req_get.get('awaiting_my_review'))
+
+ filter_type = 'awaiting_review' if awaiting_review \
+ else 'awaiting_my_review' if awaiting_my_review \
+ else None
+
+ opened_by = None
+ if my:
+ opened_by = [self._rhodecode_user.user_id]
+
+ statuses = [PullRequest.STATUS_NEW, PullRequest.STATUS_OPEN]
+ if closed:
+ statuses = [PullRequest.STATUS_CLOSED]
+
+ data = self._get_pull_requests_list(
+ repo_name=self.db_repo_name, source=source,
+ filter_type=filter_type, opened_by=opened_by, statuses=statuses)
+
+ return data
diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -827,13 +827,6 @@ def make_map(config):
'method': ['DELETE']},
requirements=URL_NAME_REQUIREMENTS)
- rmap.connect('pullrequest_show_all',
- '/{repo_name}/pull-request',
- controller='pullrequests',
- action='show_all', conditions={'function': check_repo,
- 'method': ['GET']},
- requirements=URL_NAME_REQUIREMENTS, jsroute=True)
-
rmap.connect('pullrequest_comment',
'/{repo_name}/pull-request-comment/{pull_request_id}',
controller='pullrequests',
diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py
--- a/rhodecode/controllers/pullrequests.py
+++ b/rhodecode/controllers/pullrequests.py
@@ -72,124 +72,6 @@ class PullrequestsController(BaseRepoCon
c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED
c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED
- def _extract_ordering(self, request):
- column_index = safe_int(request.GET.get('order[0][column]'))
- order_dir = request.GET.get('order[0][dir]', 'desc')
- order_by = request.GET.get(
- 'columns[%s][data][sort]' % column_index, 'name_raw')
- return order_by, order_dir
-
- @LoginRequired()
- @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
- 'repository.admin')
- @HasAcceptedRepoType('git', 'hg')
- def show_all(self, repo_name):
- # filter types
- c.active = 'open'
- c.source = str2bool(request.GET.get('source'))
- c.closed = str2bool(request.GET.get('closed'))
- c.my = str2bool(request.GET.get('my'))
- c.awaiting_review = str2bool(request.GET.get('awaiting_review'))
- c.awaiting_my_review = str2bool(request.GET.get('awaiting_my_review'))
- c.repo_name = repo_name
-
- opened_by = None
- if c.my:
- c.active = 'my'
- opened_by = [c.rhodecode_user.user_id]
-
- statuses = [PullRequest.STATUS_NEW, PullRequest.STATUS_OPEN]
- if c.closed:
- c.active = 'closed'
- statuses = [PullRequest.STATUS_CLOSED]
-
- if c.awaiting_review and not c.source:
- c.active = 'awaiting'
- if c.source and not c.awaiting_review:
- c.active = 'source'
- if c.awaiting_my_review:
- c.active = 'awaiting_my'
-
- data = self._get_pull_requests_list(
- repo_name=repo_name, opened_by=opened_by, statuses=statuses)
- if not request.is_xhr:
- c.data = json.dumps(data['data'])
- c.records_total = data['recordsTotal']
- return render('/pullrequests/pullrequests.mako')
- else:
- return json.dumps(data)
-
- def _get_pull_requests_list(self, repo_name, opened_by, statuses):
- # pagination
- start = safe_int(request.GET.get('start'), 0)
- length = safe_int(request.GET.get('length'), c.visual.dashboard_items)
- order_by, order_dir = self._extract_ordering(request)
-
- if c.awaiting_review:
- pull_requests = PullRequestModel().get_awaiting_review(
- repo_name, source=c.source, opened_by=opened_by,
- statuses=statuses, offset=start, length=length,
- order_by=order_by, order_dir=order_dir)
- pull_requests_total_count = PullRequestModel(
- ).count_awaiting_review(
- repo_name, source=c.source, statuses=statuses,
- opened_by=opened_by)
- elif c.awaiting_my_review:
- pull_requests = PullRequestModel().get_awaiting_my_review(
- repo_name, source=c.source, opened_by=opened_by,
- user_id=c.rhodecode_user.user_id, statuses=statuses,
- offset=start, length=length, order_by=order_by,
- order_dir=order_dir)
- pull_requests_total_count = PullRequestModel(
- ).count_awaiting_my_review(
- repo_name, source=c.source, user_id=c.rhodecode_user.user_id,
- statuses=statuses, opened_by=opened_by)
- else:
- pull_requests = PullRequestModel().get_all(
- repo_name, source=c.source, opened_by=opened_by,
- statuses=statuses, offset=start, length=length,
- order_by=order_by, order_dir=order_dir)
- pull_requests_total_count = PullRequestModel().count_all(
- repo_name, source=c.source, statuses=statuses,
- opened_by=opened_by)
-
- from rhodecode.lib.utils import PartialRenderer
- _render = PartialRenderer('data_table/_dt_elements.mako')
- data = []
- for pr in pull_requests:
- comments = CommentsModel().get_all_comments(
- c.rhodecode_db_repo.repo_id, pull_request=pr)
-
- data.append({
- 'name': _render('pullrequest_name',
- pr.pull_request_id, pr.target_repo.repo_name),
- 'name_raw': pr.pull_request_id,
- 'status': _render('pullrequest_status',
- pr.calculated_review_status()),
- 'title': _render(
- 'pullrequest_title', pr.title, pr.description),
- 'description': h.escape(pr.description),
- 'updated_on': _render('pullrequest_updated_on',
- h.datetime_to_time(pr.updated_on)),
- 'updated_on_raw': h.datetime_to_time(pr.updated_on),
- 'created_on': _render('pullrequest_updated_on',
- h.datetime_to_time(pr.created_on)),
- 'created_on_raw': h.datetime_to_time(pr.created_on),
- 'author': _render('pullrequest_author',
- pr.author.full_contact, ),
- 'author_raw': pr.author.full_name,
- 'comments': _render('pullrequest_comments', len(comments)),
- 'comments_raw': len(comments),
- 'closed': pr.is_closed(),
- })
- # json used to render the grid
- data = ({
- 'data': data,
- 'recordsTotal': pull_requests_total_count,
- 'recordsFiltered': pull_requests_total_count,
- })
- return data
-
@LoginRequired()
@NotAnonymous()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
diff --git a/rhodecode/public/css/panels.less b/rhodecode/public/css/panels.less
--- a/rhodecode/public/css/panels.less
+++ b/rhodecode/public/css/panels.less
@@ -42,6 +42,10 @@
.panel-body {
padding: @panel-padding;
+
+ &.panel-body-min-height {
+ min-height: 150px
+ }
}
.panel-footer {
diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js
--- a/rhodecode/public/js/rhodecode/routes.js
+++ b/rhodecode/public/js/rhodecode/routes.js
@@ -34,7 +34,6 @@ function registerRCRoutes() {
pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
- pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
pyroutes.register('pullrequest_comment', '/%(repo_name)s/pull-request-comment/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request-comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
pyroutes.register('changelog_home', '/%(repo_name)s/changelog', ['repo_name']);
@@ -106,6 +105,8 @@ function registerRCRoutes() {
pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
+ pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
+ pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
diff --git a/rhodecode/templates/base/base.mako b/rhodecode/templates/base/base.mako
--- a/rhodecode/templates/base/base.mako
+++ b/rhodecode/templates/base/base.mako
@@ -234,7 +234,7 @@
## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
%if c.rhodecode_db_repo.repo_type in ['git','hg']:
-