##// END OF EJS Templates
drafts: support draft in commits view...
milka -
r4555:57bb7bdc default
parent child Browse files
Show More
@@ -380,49 +380,36 b' class RepoCommitsView(RepoAppView):'
380 380 commit_id = self.request.matchdict['commit_id']
381 381 return self._commit(commit_id, method='download')
382 382
383 @LoginRequired()
384 @NotAnonymous()
385 @HasRepoPermissionAnyDecorator(
386 'repository.read', 'repository.write', 'repository.admin')
387 @CSRFRequired()
388 @view_config(
389 route_name='repo_commit_comment_create', request_method='POST',
390 renderer='json_ext')
391 def repo_commit_comment_create(self):
383 def _commit_comments_create(self, commit_id, comments):
392 384 _ = self.request.translate
393 commit_id = self.request.matchdict['commit_id']
385 data = {}
386 if not comments:
387 return
388
389 commit = self.db_repo.get_commit(commit_id)
394 390
395 c = self.load_default_context()
396 status = self.request.POST.get('changeset_status', None)
397 is_draft = str2bool(self.request.POST.get('draft'))
398 text = self.request.POST.get('text')
399 comment_type = self.request.POST.get('comment_type')
400 resolves_comment_id = self.request.POST.get('resolves_comment_id', None)
401 f_path = self.request.POST.get('f_path')
402 line_no = self.request.POST.get('line')
403 target_elem_id = 'file-{}'.format(h.safeid(h.safe_unicode(f_path)))
391 all_drafts = len([x for x in comments if str2bool(x['is_draft'])]) == len(comments)
392 for entry in comments:
393 c = self.load_default_context()
394 comment_type = entry['comment_type']
395 text = entry['text']
396 status = entry['status']
397 is_draft = str2bool(entry['is_draft'])
398 resolves_comment_id = entry['resolves_comment_id']
399 f_path = entry['f_path']
400 line_no = entry['line']
401 target_elem_id = 'file-{}'.format(h.safeid(h.safe_unicode(f_path)))
404 402
405 if status:
406 text = text or (_('Status change %(transition_icon)s %(status)s')
407 % {'transition_icon': '>',
408 'status': ChangesetStatus.get_status_lbl(status)})
403 if status:
404 text = text or (_('Status change %(transition_icon)s %(status)s')
405 % {'transition_icon': '>',
406 'status': ChangesetStatus.get_status_lbl(status)})
409 407
410 multi_commit_ids = []
411 for _commit_id in self.request.POST.get('commit_ids', '').split(','):
412 if _commit_id not in ['', None, EmptyCommit.raw_id]:
413 if _commit_id not in multi_commit_ids:
414 multi_commit_ids.append(_commit_id)
415
416 commit_ids = multi_commit_ids or [commit_id]
417
418 data = {}
419 # Multiple comments for each passed commit id
420 for current_id in filter(None, commit_ids):
421 408 comment = CommentsModel().create(
422 409 text=text,
423 410 repo=self.db_repo.repo_id,
424 411 user=self._rhodecode_db_user.user_id,
425 commit_id=current_id,
412 commit_id=commit_id,
426 413 f_path=f_path,
427 414 line_no=line_no,
428 415 status_change=(ChangesetStatus.get_status_lbl(status)
@@ -438,9 +425,9 b' class RepoCommitsView(RepoAppView):'
438 425
439 426 # get status if set !
440 427 if status:
428 # `dont_allow_on_closed_pull_request = True` means
441 429 # if latest status was from pull request and it's closed
442 430 # disallow changing status !
443 # dont_allow_on_closed_pull_request = True !
444 431
445 432 try:
446 433 ChangesetStatusModel().set_status(
@@ -448,7 +435,7 b' class RepoCommitsView(RepoAppView):'
448 435 status,
449 436 self._rhodecode_db_user.user_id,
450 437 comment,
451 revision=current_id,
438 revision=commit_id,
452 439 dont_allow_on_closed_pull_request=True
453 440 )
454 441 except StatusChangeOnClosedPullRequestError:
@@ -458,11 +445,15 b' class RepoCommitsView(RepoAppView):'
458 445 h.flash(msg, category='warning')
459 446 raise HTTPFound(h.route_path(
460 447 'repo_commit', repo_name=self.db_repo_name,
461 commit_id=current_id))
448 commit_id=commit_id))
449
450 Session().flush()
451 # this is somehow required to get access to some relationship
452 # loaded on comment
453 Session().refresh(comment)
462 454
463 455 # skip notifications for drafts
464 456 if not is_draft:
465 commit = self.db_repo.get_commit(current_id)
466 457 CommentsModel().trigger_commit_comment_hook(
467 458 self.db_repo, self._rhodecode_user, 'create',
468 459 data={'comment': comment, 'commit': commit})
@@ -471,6 +462,8 b' class RepoCommitsView(RepoAppView):'
471 462 data[comment_id] = {
472 463 'target_id': target_elem_id
473 464 }
465 Session().flush()
466
474 467 c.co = comment
475 468 c.at_version_num = 0
476 469 c.is_new = True
@@ -481,21 +474,25 b' class RepoCommitsView(RepoAppView):'
481 474 data[comment_id].update(comment.get_dict())
482 475 data[comment_id].update({'rendered_text': rendered_comment})
483 476
484 # skip channelstream for draft comments
485 if not is_draft:
486 comment_broadcast_channel = channelstream.comment_channel(
487 self.db_repo_name, commit_obj=commit)
488
489 comment_data = data
490 posted_comment_type = 'inline' if is_inline else 'general'
491 channelstream.comment_channelstream_push(
492 self.request, comment_broadcast_channel, self._rhodecode_user,
493 _('posted a new {} comment').format(posted_comment_type),
494 comment_data=comment_data)
495
496 477 # finalize, commit and redirect
497 478 Session().commit()
498 479
480 # skip channelstream for draft comments
481 if not all_drafts:
482 comment_broadcast_channel = channelstream.comment_channel(
483 self.db_repo_name, commit_obj=commit)
484
485 comment_data = data
486 posted_comment_type = 'inline' if is_inline else 'general'
487 if len(data) == 1:
488 msg = _('posted {} new {} comment').format(len(data), posted_comment_type)
489 else:
490 msg = _('posted {} new {} comments').format(len(data), posted_comment_type)
491
492 channelstream.comment_channelstream_push(
493 self.request, comment_broadcast_channel, self._rhodecode_user, msg,
494 comment_data=comment_data)
495
499 496 return data
500 497
501 498 @LoginRequired()
@@ -504,6 +501,44 b' class RepoCommitsView(RepoAppView):'
504 501 'repository.read', 'repository.write', 'repository.admin')
505 502 @CSRFRequired()
506 503 @view_config(
504 route_name='repo_commit_comment_create', request_method='POST',
505 renderer='json_ext')
506 def repo_commit_comment_create(self):
507 _ = self.request.translate
508 commit_id = self.request.matchdict['commit_id']
509
510 multi_commit_ids = []
511 for _commit_id in self.request.POST.get('commit_ids', '').split(','):
512 if _commit_id not in ['', None, EmptyCommit.raw_id]:
513 if _commit_id not in multi_commit_ids:
514 multi_commit_ids.append(_commit_id)
515
516 commit_ids = multi_commit_ids or [commit_id]
517
518 data = []
519 # Multiple comments for each passed commit id
520 for current_id in filter(None, commit_ids):
521 comment_data = {
522 'comment_type': self.request.POST.get('comment_type'),
523 'text': self.request.POST.get('text'),
524 'status': self.request.POST.get('changeset_status', None),
525 'is_draft': self.request.POST.get('draft'),
526 'resolves_comment_id': self.request.POST.get('resolves_comment_id', None),
527 'close_pull_request': self.request.POST.get('close_pull_request'),
528 'f_path': self.request.POST.get('f_path'),
529 'line': self.request.POST.get('line'),
530 }
531 comment = self._commit_comments_create(commit_id=current_id, comments=[comment_data])
532 data.append(comment)
533
534 return data if len(data) > 1 else data[0]
535
536 @LoginRequired()
537 @NotAnonymous()
538 @HasRepoPermissionAnyDecorator(
539 'repository.read', 'repository.write', 'repository.admin')
540 @CSRFRequired()
541 @view_config(
507 542 route_name='repo_commit_comment_preview', request_method='POST',
508 543 renderer='string', xhr=True)
509 544 def repo_commit_comment_preview(self):
@@ -690,6 +725,7 b' class RepoCommitsView(RepoAppView):'
690 725 def repo_commit_comment_edit(self):
691 726 self.load_default_context()
692 727
728 commit_id = self.request.matchdict['commit_id']
693 729 comment_id = self.request.matchdict['comment_id']
694 730 comment = ChangesetComment.get_or_404(comment_id)
695 731
@@ -742,11 +778,11 b' class RepoCommitsView(RepoAppView):'
742 778 if not comment_history:
743 779 raise HTTPNotFound()
744 780
745 commit_id = self.request.matchdict['commit_id']
746 commit = self.db_repo.get_commit(commit_id)
747 CommentsModel().trigger_commit_comment_hook(
748 self.db_repo, self._rhodecode_user, 'edit',
749 data={'comment': comment, 'commit': commit})
781 if not comment.draft:
782 commit = self.db_repo.get_commit(commit_id)
783 CommentsModel().trigger_commit_comment_hook(
784 self.db_repo, self._rhodecode_user, 'edit',
785 data={'comment': comment, 'commit': commit})
750 786
751 787 Session().commit()
752 788 return {
@@ -1523,9 +1523,9 b' class RepoPullRequestsView(RepoAppView, '
1523 1523 def _pull_request_comments_create(self, pull_request, comments):
1524 1524 _ = self.request.translate
1525 1525 data = {}
1526 pull_request_id = pull_request.pull_request_id
1527 1526 if not comments:
1528 1527 return
1528 pull_request_id = pull_request.pull_request_id
1529 1529
1530 1530 all_drafts = len([x for x in comments if str2bool(x['is_draft'])]) == len(comments)
1531 1531
@@ -1616,9 +1616,11 b' class RepoPullRequestsView(RepoAppView, '
1616 1616 # loaded on comment
1617 1617 Session().refresh(comment)
1618 1618
1619 PullRequestModel().trigger_pull_request_hook(
1620 pull_request, self._rhodecode_user, 'comment',
1621 data={'comment': comment})
1619 # skip notifications for drafts
1620 if not is_draft:
1621 PullRequestModel().trigger_pull_request_hook(
1622 pull_request, self._rhodecode_user, 'comment',
1623 data={'comment': comment})
1622 1624
1623 1625 # we now calculate the status of pull request, and based on that
1624 1626 # calculation we set the commits status
@@ -1647,16 +1649,16 b' class RepoPullRequestsView(RepoAppView, '
1647 1649 Session().commit()
1648 1650
1649 1651 # skip channelstream for draft comments
1650 if all_drafts:
1652 if not all_drafts:
1651 1653 comment_broadcast_channel = channelstream.comment_channel(
1652 1654 self.db_repo_name, pull_request_obj=pull_request)
1653 1655
1654 1656 comment_data = data
1655 comment_type = 'inline' if is_inline else 'general'
1657 posted_comment_type = 'inline' if is_inline else 'general'
1656 1658 if len(data) == 1:
1657 msg = _('posted {} new {} comment').format(len(data), comment_type)
1659 msg = _('posted {} new {} comment').format(len(data), posted_comment_type)
1658 1660 else:
1659 msg = _('posted {} new {} comments').format(len(data), comment_type)
1661 msg = _('posted {} new {} comments').format(len(data), posted_comment_type)
1660 1662
1661 1663 channelstream.comment_channelstream_push(
1662 1664 self.request, comment_broadcast_channel, self._rhodecode_user, msg,
@@ -1782,11 +1784,6 b' class RepoPullRequestsView(RepoAppView, '
1782 1784 log.debug('comment: forbidden because pull request is closed')
1783 1785 raise HTTPForbidden()
1784 1786
1785 if not comment:
1786 log.debug('Comment with id:%s not found, skipping', comment_id)
1787 # comment already deleted in another call probably
1788 return True
1789
1790 1787 if comment.pull_request.is_closed():
1791 1788 # don't allow deleting comments on closed pull request
1792 1789 raise HTTPForbidden()
@@ -1837,10 +1834,10 b' class RepoPullRequestsView(RepoAppView, '
1837 1834 raise HTTPNotFound()
1838 1835
1839 1836 Session().commit()
1840
1841 PullRequestModel().trigger_pull_request_hook(
1842 pull_request, self._rhodecode_user, 'comment_edit',
1843 data={'comment': comment})
1837 if not comment.draft:
1838 PullRequestModel().trigger_pull_request_hook(
1839 pull_request, self._rhodecode_user, 'comment_edit',
1840 data={'comment': comment})
1844 1841
1845 1842 return {
1846 1843 'comment_history_id': comment_history.comment_history_id,
@@ -509,9 +509,9 b' form.comment-form {'
509 509 }
510 510
511 511 .toolbar-text {
512 height: 42px;
512 height: 28px;
513 513 display: table-cell;
514 vertical-align: bottom;
514 vertical-align: baseline;
515 515 font-size: 11px;
516 516 color: @grey4;
517 517 text-align: right;
@@ -387,6 +387,7 b' function registerRCRoutes() {'
387 387 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
388 388 pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
389 389 pyroutes.register('pullrequest_draft_comments_submit', '/%(repo_name)s/pull-request/%(pull_request_id)s/draft_comments_submit', ['repo_name', 'pull_request_id']);
390 pyroutes.register('commit_draft_comments_submit', '/%(repo_name)s/changeset/%(commit_id)s/draft_comments_submit', ['repo_name', 'commit_id']);
390 391 pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
391 392 pyroutes.register('repo_artifacts_data', '/%(repo_name)s/artifacts_data', ['repo_name']);
392 393 pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']);
@@ -700,7 +700,16 b' var CommentsController = function() {'
700 700 var $comment = $node.closest('.comment');
701 701 var comment_id = $($comment).data('commentId');
702 702 var isDraft = $($comment).data('commentDraft');
703 var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
703
704 var pullRequestId = templateContext.pull_request_data.pull_request_id;
705 var commitId = templateContext.commit_data.commit_id;
706
707 if (pullRequestId) {
708 var url = pyroutes.url('pullrequest_comment_delete', {"comment_id": comment_id, "repo_name": templateContext.repo_name, "pull_request_id": pullRequestId})
709 } else if (commitId) {
710 var url = pyroutes.url('repo_commit_comment_delete', {"comment_id": comment_id, "repo_name": templateContext.repo_name, "commit_id": commitId})
711 }
712
704 713 var postData = {
705 714 'csrf_token': CSRF_TOKEN
706 715 };
@@ -756,16 +765,20 b' var CommentsController = function() {'
756 765
757 766 this._finalizeDrafts = function(commentIds) {
758 767
759 // remove the drafts so we can lock them before submit.
768 var pullRequestId = templateContext.pull_request_data.pull_request_id;
769 var commitId = templateContext.commit_data.commit_id;
770
771 if (pullRequestId) {
772 var url = pyroutes.url('pullrequest_draft_comments_submit', {"repo_name": templateContext.repo_name, "pull_request_id": pullRequestId})
773 } else if (commitId) {
774 var url = pyroutes.url('commit_draft_comments_submit', {"repo_name": templateContext.repo_name, "commit_id": commitId})
775 }
776
777 // remove the drafts so we can lock them before submit.
760 778 $.each(commentIds, function(idx, val){
761 779 $('#comment-{0}'.format(val)).remove();
762 780 })
763 781
764 var params = {
765 'pull_request_id': templateContext.pull_request_data.pull_request_id,
766 'repo_name': templateContext.repo_name,
767 };
768 var url = pyroutes.url('pullrequest_draft_comments_submit', params)
769 782 var postData = {'comments': commentIds, 'csrf_token': CSRF_TOKEN};
770 783
771 784 var submitSuccessCallback = function(json_data) {
@@ -24,8 +24,6 b''
24 24
25 25 <%def name="main()">
26 26 <script type="text/javascript">
27 // TODO: marcink switch this to pyroutes
28 AJAX_COMMENT_DELETE_URL = "${h.route_path('repo_commit_comment_delete',repo_name=c.repo_name,commit_id=c.commit.raw_id,comment_id='__COMMENT_ID__')}";
29 27 templateContext.commit_data.commit_id = "${c.commit.raw_id}";
30 28 </script>
31 29
@@ -542,7 +542,7 b''
542 542
543 543 <div class="toolbar-text">
544 544 <% renderer_url = '<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper()) %>
545 <span>${_('Styling with {} is supported.').format(renderer_url)|n}
545 <span>${_('{} is supported.').format(renderer_url)|n}
546 546
547 547 <i class="icon-info-circled tooltip-hovercard"
548 548 data-hovercard-alt="ALT"
@@ -32,8 +32,6 b''
32 32 %>
33 33
34 34 <script type="text/javascript">
35 // TODO: marcink switch this to pyroutes
36 AJAX_COMMENT_DELETE_URL = "${h.route_path('pullrequest_comment_delete',repo_name=c.repo_name,pull_request_id=c.pull_request.pull_request_id,comment_id='__COMMENT_ID__')}";
37 35 templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
38 36 templateContext.pull_request_data.pull_request_version = '${request.GET.get('version', '')}';
39 37 </script>
General Comments 0
You need to be logged in to leave comments. Login now