diff --git a/rhodecode/controllers/changeset.py b/rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py +++ b/rhodecode/controllers/changeset.py @@ -335,6 +335,7 @@ class ChangesetController(BaseRepoContro status = request.POST.get('changeset_status', None) text = request.POST.get('text') comment_type = request.POST.get('comment_type') + resolves_comment_id = request.POST.get('resolves_comment_id', None) if status: text = text or (_('Status change %(transition_icon)s %(status)s') @@ -358,7 +359,8 @@ class ChangesetController(BaseRepoContro status_change=(ChangesetStatus.get_status_lbl(status) if status else None), status_change_type=status, - comment_type=comment_type + comment_type=comment_type, + resolves_comment_id=resolves_comment_id ) c.inline_comment = True if comment.line_no else False diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py --- a/rhodecode/controllers/pullrequests.py +++ b/rhodecode/controllers/pullrequests.py @@ -904,7 +904,7 @@ class PullrequestsController(BaseRepoCon status = request.POST.get('changeset_status', None) text = request.POST.get('text') comment_type = request.POST.get('comment_type') - resolves_comment_id = request.POST.get('resolves_comment_id') + resolves_comment_id = request.POST.get('resolves_comment_id', None) if status and '_closed' in status: close_pr = True diff --git a/rhodecode/public/css/comments.less b/rhodecode/public/css/comments.less --- a/rhodecode/public/css/comments.less +++ b/rhodecode/public/css/comments.less @@ -72,6 +72,26 @@ tr.inline-comments div { color: @color5; font-family: @text-bold-italic; } + + .resolve { + cursor: pointer; + text-decoration: underline; + } + + .resolved { + text-decoration: line-through; + color: @color1; + } + .resolved a { + text-decoration: line-through; + color: @color1; + } + .resolve-text { + color: @color1; + margin: 2px 8px; + font-family: @text-italic; + } + } @@ -195,7 +215,6 @@ tr.inline-comments div { } } - .text { clear: both; .border-radius(@border-radius); diff --git a/rhodecode/public/js/src/rhodecode/codemirror.js b/rhodecode/public/js/src/rhodecode/codemirror.js --- a/rhodecode/public/js/src/rhodecode/codemirror.js +++ b/rhodecode/public/js/src/rhodecode/codemirror.js @@ -370,7 +370,7 @@ var initCommentBoxCodeMirror = function( hint: function(CodeMirror, data, completion) { CodeMirror.replaceRange("", completion.from || data.from, completion.to || data.to, "complete"); - $('#change_status').select2("val", 'approved').trigger('change'); + $('#change_status_general').select2("val", 'approved').trigger('change'); }, render: function(elt, data, completion) { var el = document.createElement('div'); @@ -388,7 +388,7 @@ var initCommentBoxCodeMirror = function( hint: function(CodeMirror, data, completion) { CodeMirror.replaceRange("", completion.from || data.from, completion.to || data.to, "complete"); - $('#change_status').select2("val", 'rejected').trigger('change'); + $('#change_status_general').select2("val", 'rejected').trigger('change'); }, render: function(elt, data, completion) { var el = document.createElement('div'); diff --git a/rhodecode/public/js/src/rhodecode/comments.js b/rhodecode/public/js/src/rhodecode/comments.js --- a/rhodecode/public/js/src/rhodecode/comments.js +++ b/rhodecode/public/js/src/rhodecode/comments.js @@ -106,6 +106,11 @@ var linkifyComments = function(comments) }; +var bindToggleButtons = function() { + $('.comment-toggle').on('click', function() { + $(this).parent().nextUntil('tr.line').toggle('inline-comments'); + }); +}; /* Comment form for main and inline comments */ @@ -156,7 +161,7 @@ var linkifyComments = function(comments) this.cmBox = this.withLineNo('#text'); this.cm = initCommentBoxCodeMirror(this.cmBox, this.initAutocompleteActions); - this.statusChange = '#change_status'; + this.statusChange = this.withLineNo('#change_status'); this.submitForm = formElement; this.submitButton = $(this.submitForm).find('input[type="submit"]'); @@ -171,6 +176,12 @@ var linkifyComments = function(comments) $(this.commentType).prop('disabled', true); $(this.commentType).addClass('disabled'); + // disable select + setTimeout(function() { + $(self.statusChange).select2('readonly', true); + }, 10); + + var resolvedInfo = ( '
  • ' + '' + @@ -203,6 +214,13 @@ var linkifyComments = function(comments) 'CommentForm requires pullRequestId, or commitId to be specified.') } + // FUNCTIONS and helpers + var self = this; + + this.isInline = function(){ + return this.lineNo && this.lineNo != 'general'; + }; + this.getCmInstance = function(){ return this.cm }; @@ -214,8 +232,6 @@ var linkifyComments = function(comments) } }; - var self = this; - this.getCommentStatus = function() { return $(this.submitForm).find(this.statusChange).val(); }; @@ -260,7 +276,7 @@ var linkifyComments = function(comments) }); $(this.submitForm).find(this.statusChange).on('change', function() { var status = self.getCommentStatus(); - if (status && self.lineNo == 'general') { + if (status && !self.isInline()) { $(self.submitButton).prop('disabled', false); } @@ -325,6 +341,7 @@ var linkifyComments = function(comments) var submitEvent = true; self.setActionButtonsDisabled(true, excludeCancelBtn, submitEvent); self.cm.setOption("readOnly", true); + var postData = { 'text': text, 'changeset_status': status, @@ -343,9 +360,9 @@ var linkifyComments = function(comments) bindDeleteCommentButtons(); timeagoActivate(); - //mark visually which comment was resolved + // mark visually which comment was resolved if (resolvesCommentId) { - this.markCommentResolved(resolvesCommentId); + self.markCommentResolved(resolvesCommentId); } } }; @@ -595,6 +612,62 @@ var CommentsController = function() { $node.closest('tr').toggleClass('hide-line-comments'); }; + this.createCommentForm = function(formElement, lineno, placeholderText, initAutocompleteActions, resolvesCommentId){ + var pullRequestId = templateContext.pull_request_data.pull_request_id; + var commitId = templateContext.commit_data.commit_id; + + var commentForm = new CommentForm( + formElement, commitId, pullRequestId, lineno, initAutocompleteActions, resolvesCommentId); + var cm = commentForm.getCmInstance(); + + if (resolvesCommentId){ + var placeholderText = _gettext('Leave a comment, or click resolve button to resolve TODO comment #{0}').format(resolvesCommentId); + } + + setTimeout(function() { + // callbacks + if (cm !== undefined) { + commentForm.setPlaceholder(placeholderText); + if (commentForm.isInline()) { + cm.focus(); + cm.refresh(); + } + } + }, 10); + + // trigger scrolldown to the resolve comment, since it might be away + // from the clicked + if (resolvesCommentId){ + var actionNode = $(commentForm.resolvesActionId).offset(); + + setTimeout(function() { + if (actionNode) { + $('body, html').animate({scrollTop: actionNode.top}, 10); + } + }, 100); + } + + return commentForm; + }; + + this.createGeneralComment = function(lineNo, placeholderText, resolvesCommentId){ + + var tmpl = $('#cb-comment-general-form-template').html(); + tmpl = tmpl.format(null, 'general'); + var $form = $(tmpl); + + var curForm = $('#cb-comment-general-form-placeholder').find('form'); + if (curForm){ + curForm.remove(); + } + $('#cb-comment-general-form-placeholder').append($form); + + var _form = $($form[0]); + var commentForm = this.createCommentForm( + _form, lineNo, placeholderText, true, resolvesCommentId); + commentForm.initStatusChangeSelector(); + }; + this.createComment = function(node, resolutionComment) { var resolvesCommentId = resolutionComment || null; var $node = $(node); @@ -602,12 +675,13 @@ var CommentsController = function() { var $form = $td.find('.comment-inline-form'); if (!$form.length) { - var tmpl = $('#cb-comment-inline-form-template').html(); + var $filediff = $node.closest('.filediff'); $filediff.removeClass('hide-comments'); var f_path = $filediff.attr('data-f-path'); var lineno = self.getLineNumber(node); - + // create a new HTML from template + var tmpl = $('#cb-comment-inline-form-template').html(); tmpl = tmpl.format(f_path, lineno); $form = $(tmpl); @@ -620,12 +694,18 @@ var CommentsController = function() { $td.find('.cb-comment-add-button').before($form); - var pullRequestId = templateContext.pull_request_data.pull_request_id; - var commitId = templateContext.commit_data.commit_id; + var placeholderText = _gettext('Leave a comment on line {0}.').format(lineno); var _form = $($form[0]).find('form'); - var commentForm = new CommentForm(_form, commitId, pullRequestId, lineno, false, resolvesCommentId); - var cm = commentForm.getCmInstance(); + var commentForm = this.createCommentForm( + _form, lineno, placeholderText, false, resolvesCommentId); + + $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({ + form: _form, + parent: $td[0], + lineno: lineno, + f_path: f_path} + ); // set a CUSTOM submit handler for inline comments. commentForm.setHandleFormSubmit(function(o) { @@ -693,36 +773,6 @@ var CommentsController = function() { commentForm.submitUrl, postData, submitSuccessCallback, submitFailCallback); }); - if (resolvesCommentId){ - var placeholderText = _gettext('Leave a comment, or click resolve button to resolve TODO comment #{0}').format(resolvesCommentId); - - } else { - var placeholderText = _gettext('Leave a comment on line {0}.').format(lineno); - } - - setTimeout(function() { - // callbacks - if (cm !== undefined) { - commentForm.setPlaceholder(placeholderText); - cm.focus(); - cm.refresh(); - } - }, 10); - - $.Topic('/ui/plugins/code/comment_form_built').prepareOrPublish({ - form: _form, - parent: $td[0], - lineno: lineno, - f_path: f_path} - ); - - // trigger hash - if (resolvesCommentId){ - var resolveAction = $(commentForm.resolvesActionId); - setTimeout(function() { - $('body, html').animate({ scrollTop: resolveAction.offset().top }, 10); - }, 100); - } } $form.addClass('comment-inline-form-open'); @@ -734,16 +784,10 @@ var CommentsController = function() { var comment = $('#comment-'+commentId); var commentData = comment.data(); - if (commentData.commentInline) { - var resolutionComment = true; this.createComment(comment, commentId) } else { - - this.createComment(comment, commentId) - - console.log('TODO') - console.log(commentId) + Rhodecode.comments.createGeneralComment('general', "$placeholder", commentId) } return false; diff --git a/rhodecode/templates/changeset/changeset_file_comment.mako b/rhodecode/templates/changeset/changeset_file_comment.mako --- a/rhodecode/templates/changeset/changeset_file_comment.mako +++ b/rhodecode/templates/changeset/changeset_file_comment.mako @@ -196,24 +196,19 @@ %> % if c.rhodecode_user.username != h.DEFAULT_USER: -
    +
    + ## template generated for injection + ${comment_form(form_type='general', review_statuses=c.commit_statuses, form_extras=form_extras)} +
    + +
    ## inject form here - ${comment_form(form_type='general', form_id='general_comment', lineno_id='general', review_statuses=c.commit_statuses, form_extras=form_extras)}
    - - % else: ## form state when not logged in
    @@ -313,7 +308,7 @@ % if review_statuses:
    - ## Placeholder % for status, lbl in review_statuses: diff --git a/rhodecode/templates/debug_style/collapsable-content.html b/rhodecode/templates/debug_style/collapsable-content.html --- a/rhodecode/templates/debug_style/collapsable-content.html +++ b/rhodecode/templates/debug_style/collapsable-content.html @@ -868,7 +868,7 @@ return formatChangeStatus(data, escapeMarkup); }; - $('#change_status').select2({ + $('#change_status_general').select2({ placeholder: "Status Review", formatResult: formatResult, formatSelection: formatSelection,