Mercurial > kallithea
changeset 4281:6564d82e1469
pull requests: add new "my" page, separate from "my account" and prominently shown in the page headers
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Fri, 18 Jul 2014 18:44:54 +0200 |
parents | 27f498ee6db0 |
children | 99997d8f31eb |
files | kallithea/config/routing.py kallithea/controllers/pullrequests.py kallithea/lib/base.py kallithea/model/pull_request.py kallithea/templates/base/base.html kallithea/templates/pullrequests/pullrequest_show_my.html kallithea/templates/pullrequests/pullrequest_show_my_data.html |
diffstat | 7 files changed, 230 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/config/routing.py Tue Jul 02 00:37:01 2013 +0200 +++ b/kallithea/config/routing.py Fri Jul 18 18:44:54 2014 +0200 @@ -718,6 +718,15 @@ action='show_all', conditions=dict(function=check_repo, method=["GET"])) + rmap.connect('my_pullrequests', + '/my_pullrequests', + controller='pullrequests', + action='show_my', conditions=dict(method=["GET"])) + rmap.connect('my_pullrequests_data', + '/my_pullrequests_data', + controller='pullrequests', + action='show_my_data', conditions=dict(method=["GET"])) + rmap.connect('pullrequest_comment', '/{repo_name:.*?}/pull-request-comment/{pull_request_id}', controller='pullrequests',
--- a/kallithea/controllers/pullrequests.py Tue Jul 02 00:37:01 2013 +0200 +++ b/kallithea/controllers/pullrequests.py Fri Jul 18 18:44:54 2014 +0200 @@ -48,7 +48,8 @@ from kallithea.lib.vcs.utils import safe_str from kallithea.lib.vcs.exceptions import EmptyRepositoryError from kallithea.lib.diffs import LimitedDiffContainer -from kallithea.model.db import PullRequest, ChangesetStatus, ChangesetComment +from kallithea.model.db import PullRequest, ChangesetStatus, ChangesetComment,\ + PullRequestReviewers from kallithea.model.pull_request import PullRequestModel from kallithea.model.meta import Session from kallithea.model.repo import RepoModel @@ -257,6 +258,34 @@ return render('/pullrequests/pullrequest_show_all.html') @LoginRequired() + def show_my(self): # my_account_my_pullrequests + c.show_closed = request.GET.get('pr_show_closed') + return render('/pullrequests/pullrequest_show_my.html') + + @NotAnonymous() + def show_my_data(self): + c.show_closed = request.GET.get('pr_show_closed') + + def _filter(pr): + s = sorted(pr, key=lambda o: o.created_on, reverse=True) + if not c.show_closed: + s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s) + return s + + c.my_pull_requests = _filter(PullRequest.query()\ + .filter(PullRequest.user_id == + self.authuser.user_id)\ + .all()) + + c.participate_in_pull_requests = _filter(PullRequest.query()\ + .join(PullRequestReviewers)\ + .filter(PullRequestReviewers.user_id == + self.authuser.user_id)\ + ) + + return render('/pullrequests/pullrequest_show_my_data.html') + + @LoginRequired() @NotAnonymous() @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin')
--- a/kallithea/lib/base.py Tue Jul 02 00:37:01 2013 +0200 +++ b/kallithea/lib/base.py Fri Jul 18 18:44:54 2014 +0200 @@ -55,6 +55,7 @@ from kallithea.model.notification import NotificationModel from kallithea.model.scm import ScmModel from kallithea.model.meta import Session +from kallithea.model.pull_request import PullRequestModel log = logging.getLogger(__name__) @@ -319,6 +320,9 @@ .get_unread_cnt_for_user(c.authuser.user_id) self.cut_off_limit = safe_int(config.get('cut_off_limit')) + + c.my_pr_count = PullRequestModel().get_pullrequest_cnt_for_user(c.authuser.user_id) + self.sa = meta.Session self.scm_model = ScmModel(self.sa)
--- a/kallithea/model/pull_request.py Tue Jul 02 00:37:01 2013 +0200 +++ b/kallithea/model/pull_request.py Fri Jul 18 18:44:54 2014 +0200 @@ -49,6 +49,13 @@ def __get_pull_request(self, pull_request): return self._get_instance(PullRequest, pull_request) + def get_pullrequest_cnt_for_user(self, user): + return PullRequest.query()\ + .join(PullRequestReviewers)\ + .filter(PullRequestReviewers.user_id == user)\ + .filter(PullRequest.status != PullRequest.STATUS_CLOSED)\ + .count() + def get_all(self, repo_name, from_=False, closed=False): """Get all PRs for repo. Default is all PRs to the repo, PRs from the repo if from_.
--- a/kallithea/templates/base/base.html Tue Jul 02 00:37:01 2013 +0200 +++ b/kallithea/templates/base/base.html Fri Jul 18 18:44:54 2014 +0200 @@ -222,7 +222,78 @@ <!--- END CONTEXT BAR --> </%def> -<%def name="usermenu()"> +<%def name="menu(current=None)"> + <% + def is_current(selected): + if selected == current: + return h.literal('class="current"') + %> + + <ul id="quick" class="horizontal-list"> + <!-- repo switcher --> + <li ${is_current('repositories')}> + <input id="repo_switcher" name="repo_switcher" type="hidden"> + </li> + + ##ROOT MENU + %if c.authuser.username != 'default': + <li ${is_current('journal')}> + <a class="menu_link" title="${_('Show recent activity')}" href="${h.url('journal')}"> + <i class="icon-book"></i> ${_('Journal')} + </a> + </li> + %else: + <li ${is_current('journal')}> + <a class="menu_link" title="${_('Public journal')}" href="${h.url('public_journal')}"> + <i class="icon-book"></i> ${_('Public journal')} + </a> + </li> + %endif + <li ${is_current('gists')}> + <a class="menu_link childs" title="${_('Show public gists')}" href="${h.url('gists')}"> + <i class="icon-file-2"></i> ${_('Gists')} + </a> + <ul class="admin_menu"> + <li><a href="${h.url('new_gist', public=1)}"><i class="icon-file-alt"></i> ${_('Create new gist')}</a></li> + <li><a href="${h.url('gists')}"><i class="icon-copy"></i> ${_('All public gists')}</a></li> + %if c.authuser.username != 'default': + <li><a href="${h.url('gists', public=1)}"><i class="icon-copy"></i> ${_('My public gists')}</a></li> + <li><a href="${h.url('gists', private=1)}"><i class="icon-file-text"></i> ${_('My private gists')}</a></li> + %endif + </ul> + </li> + <li ${is_current('search')}> + <a class="menu_link" title="${_('Search in repositories')}" href="${h.url('search')}"> + <i class="icon-search"></i> ${_('Search')} + </a> + </li> + % if h.HasPermissionAll('hg.admin')('access admin main page'): + <li ${is_current('admin')}> + <a class="menu_link childs" title="${_('Admin')}" href="${h.url('admin_home')}"> + <i class="icon-cog"></i> ${_('Admin')} + </a> + ${admin_menu()} + </li> + % elif c.authuser.repositories_admin or c.authuser.repository_groups_admin or c.authuser.user_groups_admin: + <li ${is_current('admin')}> + <a class="menu_link childs" title="${_('Admin')}"> + <i class="icon-cog"></i> ${_('Admin')} + </a> + ${admin_menu_simple(c.authuser.repositories_admin, + c.authuser.repository_groups_admin, + c.authuser.user_groups_admin or h.HasPermissionAny('hg.usergroup.create.true')())} + </li> + % endif + + <li ${is_current('my_pullrequests')}> + <a class="menu_link" title="${_('My Pull Requests')}" href="${h.url('my_pullrequests')}"> + <i class="icon-code-fork"></i> ${_('My Pull Requests')} + %if c.my_pr_count != 0: + <span class="menu_link_notifications">${c.my_pr_count}</span> + %endif + </a> + </li> + ## USER MENU <li> <a class="menu_link childs" id="quick_login_link"> @@ -239,9 +310,9 @@ %endif </a> - <div class="user-menu"> - <div id="quick_login"> - %if c.authuser.username == 'default': + <div class="user-menu"> + <div id="quick_login"> + %if c.authuser.username == 'default': <h4>${_('Login to your account')}</h4> ${h.form(h.url('login_home',came_from=h.url.current()))} <div class="form"> @@ -278,7 +349,7 @@ </div> </div> ${h.end_form()} - %else: + %else: <div class="links_left"> <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.authuser.email,48)}" /></div> <div class="full_name">${c.authuser.full_name_or_username}</div> @@ -291,75 +362,10 @@ <li class="logout">${h.link_to(_(u'Log Out'),h.url('logout_home'))}</li> </ol> </div> - %endif + %endif + </div> </div> - </div> - </li> -</%def> - -<%def name="menu(current=None)"> - <% - def is_current(selected): - if selected == current: - return h.literal('class="current"') - %> - <ul id="quick" class="horizontal-list"> - <!-- repo switcher --> - <li ${is_current('repositories')}> - <input id="repo_switcher" name="repo_switcher" type="hidden"> - </li> - - ##ROOT MENU - %if c.authuser.username != 'default': - <li ${is_current('journal')}> - <a class="menu_link" title="${_('Show recent activity')}" href="${h.url('journal')}"> - <i class="icon-book"></i> ${_('Journal')} - </a> - </li> - %else: - <li ${is_current('journal')}> - <a class="menu_link" title="${_('Public journal')}" href="${h.url('public_journal')}"> - <i class="icon-book"></i> ${_('Public journal')} - </a> - </li> - %endif - <li ${is_current('gists')}> - <a class="menu_link childs" title="${_('Show public gists')}" href="${h.url('gists')}"> - <i class="icon-file-2"></i> ${_('Gists')} - </a> - <ul class="admin_menu"> - <li><a href="${h.url('new_gist', public=1)}"><i class="icon-file-alt"></i> ${_('Create new gist')}</a></li> - <li><a href="${h.url('gists')}"><i class="icon-copy"></i> ${_('All public gists')}</a></li> - %if c.authuser.username != 'default': - <li><a href="${h.url('gists', public=1)}"><i class="icon-copy"></i> ${_('My public gists')}</a></li> - <li><a href="${h.url('gists', private=1)}"><i class="icon-file-text"></i> ${_('My private gists')}</a></li> - %endif - </ul> - </li> - <li ${is_current('search')}> - <a class="menu_link" title="${_('Search in repositories')}" href="${h.url('search')}"> - <i class="icon-search"></i> ${_('Search')} - </a> - </li> - % if h.HasPermissionAll('hg.admin')('access admin main page'): - <li ${is_current('admin')}> - <a class="menu_link childs" title="${_('Admin')}" href="${h.url('admin_home')}"> - <i class="icon-cog"></i> ${_('Admin')} - </a> - ${admin_menu()} - </li> - % elif c.authuser.repositories_admin or c.authuser.repository_groups_admin or c.authuser.user_groups_admin: - <li ${is_current('admin')}> - <a class="menu_link childs" title="${_('Admin')}"> - <i class="icon-cog"></i> ${_('Admin')} - </a> - ${admin_menu_simple(c.authuser.repositories_admin, - c.authuser.repository_groups_admin, - c.authuser.user_groups_admin or h.HasPermissionAny('hg.usergroup.create.true')())} - </li> - % endif - ${usermenu()} <script type="text/javascript"> var visual_show_public_icon = "${c.visual.show_public_icon}" == "True";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kallithea/templates/pullrequests/pullrequest_show_my.html Fri Jul 18 18:44:54 2014 +0200 @@ -0,0 +1,49 @@ +<%inherit file="/base/base.html"/> + +<%def name="title()"> + ${_('My Pull Requests')} · ${c.site_name} +</%def> + +<%def name="breadcrumbs_links()"> + ${_('My Pull Requests')} +</%def> + +<%def name="page_nav()"> + ${self.menu('my_pullrequests')} +</%def> + +<%def name="main()"> + +<div class="box"> + <!-- box / title --> + <div class="title"> + ${self.breadcrumbs()} + </div> + + <div id="pullrequests_container" class="table"> + ## loaded via AJAX + ${_('Loading...')} + </div> + +<script type="text/javascript"> +pyroutes.register('my_pullrequests_data', "${url('my_pullrequests_data')}", []); + +var show_pullrequests = function(e){ + + var url = pyroutes.url('my_pullrequests_data'); + if(YUD.get('show_closed') && YUD.get('show_closed').checked) { + var url = pyroutes.url('my_pullrequests_data', {'pr_show_closed': '1'}); + } + ypjax(url, 'pullrequests_container', function(){ + YUE.on('show_closed','change',function (e) { + show_pullrequests(e); + }); + }); +} +show_pullrequests() + +</script> + +</div> + +</%def>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kallithea/templates/pullrequests/pullrequest_show_my_data.html Fri Jul 18 18:44:54 2014 +0200 @@ -0,0 +1,53 @@ +%if c.show_closed: + ${h.checkbox('show_closed',checked="checked", label=_('Show closed pull requests'))} +%else: + ${h.checkbox('show_closed',label=_('Show closed pull requests'))} +%endif +<div class="pullrequests_section_head">${_('Opened by me')}</div> +<ul> + %if c.my_pull_requests: + %for pull_request in c.my_pull_requests: + <li class="${'closed' if pull_request.is_closed() else ''}"> + <div style="height: 12px"> + <div style="float:left"> + <img src="${h.url('/images/icons/flag_status_%s.png' % str(pull_request.last_review_status))}" /> + <a href="${h.url('pullrequest_show',repo_name=pull_request.other_repo.repo_name,pull_request_id=pull_request.pull_request_id)}"> + ${_('Pull request #%s opened on %s') % (pull_request.pull_request_id, h.fmt_date(pull_request.created_on))} + %if pull_request.is_closed(): + (${_('Closed')}) + %endif + </a> + </div> + <div style="float:left"> + ${h.form(url('pullrequest_delete', repo_name=pull_request.other_repo.repo_name, pull_request_id=pull_request.pull_request_id),method='delete')} + ${h.submit('remove_%s' % pull_request.pull_request_id, '', title=_('Delete Pull Request'),class_="delete_icon action_button",onclick="return confirm('"+_('Confirm to delete this pull request')+"');")} + ${h.end_form()} + </div> + </div> + </li> + %endfor + %else: + <li><span class="empty_data">${_('Nothing here yet')}</span></li> + %endif +</ul> + +<div class="pullrequests_section_head" style="clear:both">${_('I participate in')}</div> +<ul> + %if c.participate_in_pull_requests: + %for pull_request in c.participate_in_pull_requests: + <li class="${'closed' if pull_request.is_closed() else ''}"> + <div style="height: 12px"> + <img src="${h.url('/images/icons/flag_status_%s.png' % str(pull_request.last_review_status))}" /> + <a href="${h.url('pullrequest_show',repo_name=pull_request.other_repo.repo_name,pull_request_id=pull_request.pull_request_id)}"> + ${_('Pull request #%s opened by %s on %s') % (pull_request.pull_request_id, pull_request.author.full_name, h.fmt_date(pull_request.created_on))} + </a> + %if pull_request.is_closed(): + (${_('Closed')}) + %endif + </div> + </li> + %endfor + %else: + <li><span class="empty_data">${_('Nothing here yet')}</span></li> + %endif +</ul>