drafts: support draft in commits view
- few tweeks on draft submition to make them fast - no hook calls etc.
This commit is contained in:
parent
37bb65c4f6
commit
e48461f9f3
8 changed files with 132 additions and 89 deletions
|
|
@ -380,49 +380,36 @@ class RepoCommitsView(RepoAppView):
|
|||
commit_id = self.request.matchdict['commit_id']
|
||||
return self._commit(commit_id, method='download')
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
@CSRFRequired()
|
||||
@view_config(
|
||||
route_name='repo_commit_comment_create', request_method='POST',
|
||||
renderer='json_ext')
|
||||
def repo_commit_comment_create(self):
|
||||
def _commit_comments_create(self, commit_id, comments):
|
||||
_ = self.request.translate
|
||||
commit_id = self.request.matchdict['commit_id']
|
||||
|
||||
c = self.load_default_context()
|
||||
status = self.request.POST.get('changeset_status', None)
|
||||
is_draft = str2bool(self.request.POST.get('draft'))
|
||||
text = self.request.POST.get('text')
|
||||
comment_type = self.request.POST.get('comment_type')
|
||||
resolves_comment_id = self.request.POST.get('resolves_comment_id', None)
|
||||
f_path = self.request.POST.get('f_path')
|
||||
line_no = self.request.POST.get('line')
|
||||
target_elem_id = 'file-{}'.format(h.safeid(h.safe_unicode(f_path)))
|
||||
|
||||
if status:
|
||||
text = text or (_('Status change %(transition_icon)s %(status)s')
|
||||
% {'transition_icon': '>',
|
||||
'status': ChangesetStatus.get_status_lbl(status)})
|
||||
|
||||
multi_commit_ids = []
|
||||
for _commit_id in self.request.POST.get('commit_ids', '').split(','):
|
||||
if _commit_id not in ['', None, EmptyCommit.raw_id]:
|
||||
if _commit_id not in multi_commit_ids:
|
||||
multi_commit_ids.append(_commit_id)
|
||||
|
||||
commit_ids = multi_commit_ids or [commit_id]
|
||||
|
||||
data = {}
|
||||
# Multiple comments for each passed commit id
|
||||
for current_id in filter(None, commit_ids):
|
||||
if not comments:
|
||||
return
|
||||
|
||||
commit = self.db_repo.get_commit(commit_id)
|
||||
|
||||
all_drafts = len([x for x in comments if str2bool(x['is_draft'])]) == len(comments)
|
||||
for entry in comments:
|
||||
c = self.load_default_context()
|
||||
comment_type = entry['comment_type']
|
||||
text = entry['text']
|
||||
status = entry['status']
|
||||
is_draft = str2bool(entry['is_draft'])
|
||||
resolves_comment_id = entry['resolves_comment_id']
|
||||
f_path = entry['f_path']
|
||||
line_no = entry['line']
|
||||
target_elem_id = 'file-{}'.format(h.safeid(h.safe_unicode(f_path)))
|
||||
|
||||
if status:
|
||||
text = text or (_('Status change %(transition_icon)s %(status)s')
|
||||
% {'transition_icon': '>',
|
||||
'status': ChangesetStatus.get_status_lbl(status)})
|
||||
|
||||
comment = CommentsModel().create(
|
||||
text=text,
|
||||
repo=self.db_repo.repo_id,
|
||||
user=self._rhodecode_db_user.user_id,
|
||||
commit_id=current_id,
|
||||
commit_id=commit_id,
|
||||
f_path=f_path,
|
||||
line_no=line_no,
|
||||
status_change=(ChangesetStatus.get_status_lbl(status)
|
||||
|
|
@ -438,9 +425,9 @@ class RepoCommitsView(RepoAppView):
|
|||
|
||||
# get status if set !
|
||||
if status:
|
||||
# `dont_allow_on_closed_pull_request = True` means
|
||||
# if latest status was from pull request and it's closed
|
||||
# disallow changing status !
|
||||
# dont_allow_on_closed_pull_request = True !
|
||||
|
||||
try:
|
||||
ChangesetStatusModel().set_status(
|
||||
|
|
@ -448,7 +435,7 @@ class RepoCommitsView(RepoAppView):
|
|||
status,
|
||||
self._rhodecode_db_user.user_id,
|
||||
comment,
|
||||
revision=current_id,
|
||||
revision=commit_id,
|
||||
dont_allow_on_closed_pull_request=True
|
||||
)
|
||||
except StatusChangeOnClosedPullRequestError:
|
||||
|
|
@ -458,11 +445,15 @@ class RepoCommitsView(RepoAppView):
|
|||
h.flash(msg, category='warning')
|
||||
raise HTTPFound(h.route_path(
|
||||
'repo_commit', repo_name=self.db_repo_name,
|
||||
commit_id=current_id))
|
||||
commit_id=commit_id))
|
||||
|
||||
Session().flush()
|
||||
# this is somehow required to get access to some relationship
|
||||
# loaded on comment
|
||||
Session().refresh(comment)
|
||||
|
||||
# skip notifications for drafts
|
||||
if not is_draft:
|
||||
commit = self.db_repo.get_commit(current_id)
|
||||
CommentsModel().trigger_commit_comment_hook(
|
||||
self.db_repo, self._rhodecode_user, 'create',
|
||||
data={'comment': comment, 'commit': commit})
|
||||
|
|
@ -471,6 +462,8 @@ class RepoCommitsView(RepoAppView):
|
|||
data[comment_id] = {
|
||||
'target_id': target_elem_id
|
||||
}
|
||||
Session().flush()
|
||||
|
||||
c.co = comment
|
||||
c.at_version_num = 0
|
||||
c.is_new = True
|
||||
|
|
@ -481,23 +474,65 @@ class RepoCommitsView(RepoAppView):
|
|||
data[comment_id].update(comment.get_dict())
|
||||
data[comment_id].update({'rendered_text': rendered_comment})
|
||||
|
||||
# skip channelstream for draft comments
|
||||
if not is_draft:
|
||||
comment_broadcast_channel = channelstream.comment_channel(
|
||||
self.db_repo_name, commit_obj=commit)
|
||||
|
||||
comment_data = data
|
||||
posted_comment_type = 'inline' if is_inline else 'general'
|
||||
channelstream.comment_channelstream_push(
|
||||
self.request, comment_broadcast_channel, self._rhodecode_user,
|
||||
_('posted a new {} comment').format(posted_comment_type),
|
||||
comment_data=comment_data)
|
||||
|
||||
# finalize, commit and redirect
|
||||
Session().commit()
|
||||
|
||||
# skip channelstream for draft comments
|
||||
if not all_drafts:
|
||||
comment_broadcast_channel = channelstream.comment_channel(
|
||||
self.db_repo_name, commit_obj=commit)
|
||||
|
||||
comment_data = data
|
||||
posted_comment_type = 'inline' if is_inline else 'general'
|
||||
if len(data) == 1:
|
||||
msg = _('posted {} new {} comment').format(len(data), posted_comment_type)
|
||||
else:
|
||||
msg = _('posted {} new {} comments').format(len(data), posted_comment_type)
|
||||
|
||||
channelstream.comment_channelstream_push(
|
||||
self.request, comment_broadcast_channel, self._rhodecode_user, msg,
|
||||
comment_data=comment_data)
|
||||
|
||||
return data
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
@CSRFRequired()
|
||||
@view_config(
|
||||
route_name='repo_commit_comment_create', request_method='POST',
|
||||
renderer='json_ext')
|
||||
def repo_commit_comment_create(self):
|
||||
_ = self.request.translate
|
||||
commit_id = self.request.matchdict['commit_id']
|
||||
|
||||
multi_commit_ids = []
|
||||
for _commit_id in self.request.POST.get('commit_ids', '').split(','):
|
||||
if _commit_id not in ['', None, EmptyCommit.raw_id]:
|
||||
if _commit_id not in multi_commit_ids:
|
||||
multi_commit_ids.append(_commit_id)
|
||||
|
||||
commit_ids = multi_commit_ids or [commit_id]
|
||||
|
||||
data = []
|
||||
# Multiple comments for each passed commit id
|
||||
for current_id in filter(None, commit_ids):
|
||||
comment_data = {
|
||||
'comment_type': self.request.POST.get('comment_type'),
|
||||
'text': self.request.POST.get('text'),
|
||||
'status': self.request.POST.get('changeset_status', None),
|
||||
'is_draft': self.request.POST.get('draft'),
|
||||
'resolves_comment_id': self.request.POST.get('resolves_comment_id', None),
|
||||
'close_pull_request': self.request.POST.get('close_pull_request'),
|
||||
'f_path': self.request.POST.get('f_path'),
|
||||
'line': self.request.POST.get('line'),
|
||||
}
|
||||
comment = self._commit_comments_create(commit_id=current_id, comments=[comment_data])
|
||||
data.append(comment)
|
||||
|
||||
return data if len(data) > 1 else data[0]
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
|
|
@ -690,6 +725,7 @@ class RepoCommitsView(RepoAppView):
|
|||
def repo_commit_comment_edit(self):
|
||||
self.load_default_context()
|
||||
|
||||
commit_id = self.request.matchdict['commit_id']
|
||||
comment_id = self.request.matchdict['comment_id']
|
||||
comment = ChangesetComment.get_or_404(comment_id)
|
||||
|
||||
|
|
@ -742,11 +778,11 @@ class RepoCommitsView(RepoAppView):
|
|||
if not comment_history:
|
||||
raise HTTPNotFound()
|
||||
|
||||
commit_id = self.request.matchdict['commit_id']
|
||||
commit = self.db_repo.get_commit(commit_id)
|
||||
CommentsModel().trigger_commit_comment_hook(
|
||||
self.db_repo, self._rhodecode_user, 'edit',
|
||||
data={'comment': comment, 'commit': commit})
|
||||
if not comment.draft:
|
||||
commit = self.db_repo.get_commit(commit_id)
|
||||
CommentsModel().trigger_commit_comment_hook(
|
||||
self.db_repo, self._rhodecode_user, 'edit',
|
||||
data={'comment': comment, 'commit': commit})
|
||||
|
||||
Session().commit()
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1523,9 +1523,9 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
def _pull_request_comments_create(self, pull_request, comments):
|
||||
_ = self.request.translate
|
||||
data = {}
|
||||
pull_request_id = pull_request.pull_request_id
|
||||
if not comments:
|
||||
return
|
||||
pull_request_id = pull_request.pull_request_id
|
||||
|
||||
all_drafts = len([x for x in comments if str2bool(x['is_draft'])]) == len(comments)
|
||||
|
||||
|
|
@ -1616,9 +1616,11 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
# loaded on comment
|
||||
Session().refresh(comment)
|
||||
|
||||
PullRequestModel().trigger_pull_request_hook(
|
||||
pull_request, self._rhodecode_user, 'comment',
|
||||
data={'comment': comment})
|
||||
# skip notifications for drafts
|
||||
if not is_draft:
|
||||
PullRequestModel().trigger_pull_request_hook(
|
||||
pull_request, self._rhodecode_user, 'comment',
|
||||
data={'comment': comment})
|
||||
|
||||
# we now calculate the status of pull request, and based on that
|
||||
# calculation we set the commits status
|
||||
|
|
@ -1647,16 +1649,16 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
Session().commit()
|
||||
|
||||
# skip channelstream for draft comments
|
||||
if all_drafts:
|
||||
if not all_drafts:
|
||||
comment_broadcast_channel = channelstream.comment_channel(
|
||||
self.db_repo_name, pull_request_obj=pull_request)
|
||||
|
||||
comment_data = data
|
||||
comment_type = 'inline' if is_inline else 'general'
|
||||
posted_comment_type = 'inline' if is_inline else 'general'
|
||||
if len(data) == 1:
|
||||
msg = _('posted {} new {} comment').format(len(data), comment_type)
|
||||
msg = _('posted {} new {} comment').format(len(data), posted_comment_type)
|
||||
else:
|
||||
msg = _('posted {} new {} comments').format(len(data), comment_type)
|
||||
msg = _('posted {} new {} comments').format(len(data), posted_comment_type)
|
||||
|
||||
channelstream.comment_channelstream_push(
|
||||
self.request, comment_broadcast_channel, self._rhodecode_user, msg,
|
||||
|
|
@ -1782,11 +1784,6 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
log.debug('comment: forbidden because pull request is closed')
|
||||
raise HTTPForbidden()
|
||||
|
||||
if not comment:
|
||||
log.debug('Comment with id:%s not found, skipping', comment_id)
|
||||
# comment already deleted in another call probably
|
||||
return True
|
||||
|
||||
if comment.pull_request.is_closed():
|
||||
# don't allow deleting comments on closed pull request
|
||||
raise HTTPForbidden()
|
||||
|
|
@ -1837,10 +1834,10 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView):
|
|||
raise HTTPNotFound()
|
||||
|
||||
Session().commit()
|
||||
|
||||
PullRequestModel().trigger_pull_request_hook(
|
||||
pull_request, self._rhodecode_user, 'comment_edit',
|
||||
data={'comment': comment})
|
||||
if not comment.draft:
|
||||
PullRequestModel().trigger_pull_request_hook(
|
||||
pull_request, self._rhodecode_user, 'comment_edit',
|
||||
data={'comment': comment})
|
||||
|
||||
return {
|
||||
'comment_history_id': comment_history.comment_history_id,
|
||||
|
|
|
|||
|
|
@ -509,9 +509,9 @@ form.comment-form {
|
|||
}
|
||||
|
||||
.toolbar-text {
|
||||
height: 42px;
|
||||
height: 28px;
|
||||
display: table-cell;
|
||||
vertical-align: bottom;
|
||||
vertical-align: baseline;
|
||||
font-size: 11px;
|
||||
color: @grey4;
|
||||
text-align: right;
|
||||
|
|
|
|||
|
|
@ -387,6 +387,7 @@ function registerRCRoutes() {
|
|||
pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
|
||||
pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
|
||||
pyroutes.register('pullrequest_draft_comments_submit', '/%(repo_name)s/pull-request/%(pull_request_id)s/draft_comments_submit', ['repo_name', 'pull_request_id']);
|
||||
pyroutes.register('commit_draft_comments_submit', '/%(repo_name)s/changeset/%(commit_id)s/draft_comments_submit', ['repo_name', 'commit_id']);
|
||||
pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
|
||||
pyroutes.register('repo_artifacts_data', '/%(repo_name)s/artifacts_data', ['repo_name']);
|
||||
pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']);
|
||||
|
|
|
|||
|
|
@ -700,7 +700,16 @@ var CommentsController = function() {
|
|||
var $comment = $node.closest('.comment');
|
||||
var comment_id = $($comment).data('commentId');
|
||||
var isDraft = $($comment).data('commentDraft');
|
||||
var url = AJAX_COMMENT_DELETE_URL.replace('__COMMENT_ID__', comment_id);
|
||||
|
||||
var pullRequestId = templateContext.pull_request_data.pull_request_id;
|
||||
var commitId = templateContext.commit_data.commit_id;
|
||||
|
||||
if (pullRequestId) {
|
||||
var url = pyroutes.url('pullrequest_comment_delete', {"comment_id": comment_id, "repo_name": templateContext.repo_name, "pull_request_id": pullRequestId})
|
||||
} else if (commitId) {
|
||||
var url = pyroutes.url('repo_commit_comment_delete', {"comment_id": comment_id, "repo_name": templateContext.repo_name, "commit_id": commitId})
|
||||
}
|
||||
|
||||
var postData = {
|
||||
'csrf_token': CSRF_TOKEN
|
||||
};
|
||||
|
|
@ -756,16 +765,20 @@ var CommentsController = function() {
|
|||
|
||||
this._finalizeDrafts = function(commentIds) {
|
||||
|
||||
// remove the drafts so we can lock them before submit.
|
||||
var pullRequestId = templateContext.pull_request_data.pull_request_id;
|
||||
var commitId = templateContext.commit_data.commit_id;
|
||||
|
||||
if (pullRequestId) {
|
||||
var url = pyroutes.url('pullrequest_draft_comments_submit', {"repo_name": templateContext.repo_name, "pull_request_id": pullRequestId})
|
||||
} else if (commitId) {
|
||||
var url = pyroutes.url('commit_draft_comments_submit', {"repo_name": templateContext.repo_name, "commit_id": commitId})
|
||||
}
|
||||
|
||||
// remove the drafts so we can lock them before submit.
|
||||
$.each(commentIds, function(idx, val){
|
||||
$('#comment-{0}'.format(val)).remove();
|
||||
})
|
||||
|
||||
var params = {
|
||||
'pull_request_id': templateContext.pull_request_data.pull_request_id,
|
||||
'repo_name': templateContext.repo_name,
|
||||
};
|
||||
var url = pyroutes.url('pullrequest_draft_comments_submit', params)
|
||||
var postData = {'comments': commentIds, 'csrf_token': CSRF_TOKEN};
|
||||
|
||||
var submitSuccessCallback = function(json_data) {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
|
||||
<%def name="main()">
|
||||
<script type="text/javascript">
|
||||
// TODO: marcink switch this to pyroutes
|
||||
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__')}";
|
||||
templateContext.commit_data.commit_id = "${c.commit.raw_id}";
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@
|
|||
|
||||
<div class="toolbar-text">
|
||||
<% renderer_url = '<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper()) %>
|
||||
<span>${_('Styling with {} is supported.').format(renderer_url)|n}
|
||||
<span>${_('{} is supported.').format(renderer_url)|n}
|
||||
|
||||
<i class="icon-info-circled tooltip-hovercard"
|
||||
data-hovercard-alt="ALT"
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@
|
|||
%>
|
||||
|
||||
<script type="text/javascript">
|
||||
// TODO: marcink switch this to pyroutes
|
||||
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__')}";
|
||||
templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id};
|
||||
templateContext.pull_request_data.pull_request_version = '${request.GET.get('version', '')}';
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue