mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 01:34:27 +00:00 
			
		
		
		
	Make Ctrl+Enter submit a pending comment (starting review) instead of submitting a single comment (#23245)
Close #23241 Before: press Ctrl+Enter in the Code Review Form, a single comment will be added. After: press Ctrl+Enter in the Code Review Form, start the review with pending comments. The old name `is_review` is not clear, so the new code use `pending_review` as the new name. Co-authored-by: delvh <leon@kske.dev> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		@@ -268,7 +268,7 @@ func DeletePullReview(ctx *context.APIContext) {
 | 
				
			|||||||
	ctx.Status(http.StatusNoContent)
 | 
						ctx.Status(http.StatusNoContent)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreatePullReview create a review to an pull request
 | 
					// CreatePullReview create a review to a pull request
 | 
				
			||||||
func CreatePullReview(ctx *context.APIContext) {
 | 
					func CreatePullReview(ctx *context.APIContext) {
 | 
				
			||||||
	// swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/reviews repository repoCreatePullReview
 | 
						// swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/reviews repository repoCreatePullReview
 | 
				
			||||||
	// ---
 | 
						// ---
 | 
				
			||||||
@@ -360,7 +360,7 @@ func CreatePullReview(ctx *context.APIContext) {
 | 
				
			|||||||
			line,
 | 
								line,
 | 
				
			||||||
			c.Body,
 | 
								c.Body,
 | 
				
			||||||
			c.Path,
 | 
								c.Path,
 | 
				
			||||||
			true, // is review
 | 
								true, // pending review
 | 
				
			||||||
			0,    // no reply
 | 
								0,    // no reply
 | 
				
			||||||
			opts.CommitID,
 | 
								opts.CommitID,
 | 
				
			||||||
		); err != nil {
 | 
							); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,7 +77,7 @@ func CreateCodeComment(ctx *context.Context) {
 | 
				
			|||||||
		signedLine,
 | 
							signedLine,
 | 
				
			||||||
		form.Content,
 | 
							form.Content,
 | 
				
			||||||
		form.TreePath,
 | 
							form.TreePath,
 | 
				
			||||||
		form.IsReview,
 | 
							!form.SingleReview,
 | 
				
			||||||
		form.Reply,
 | 
							form.Reply,
 | 
				
			||||||
		form.LatestCommitID,
 | 
							form.LatestCommitID,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -622,7 +622,7 @@ type CodeCommentForm struct {
 | 
				
			|||||||
	Side           string `binding:"Required;In(previous,proposed)"`
 | 
						Side           string `binding:"Required;In(previous,proposed)"`
 | 
				
			||||||
	Line           int64
 | 
						Line           int64
 | 
				
			||||||
	TreePath       string `form:"path" binding:"Required"`
 | 
						TreePath       string `form:"path" binding:"Required"`
 | 
				
			||||||
	IsReview       bool   `form:"is_review"`
 | 
						SingleReview   bool   `form:"single_review"`
 | 
				
			||||||
	Reply          int64  `form:"reply"`
 | 
						Reply          int64  `form:"reply"`
 | 
				
			||||||
	LatestCommitID string
 | 
						LatestCommitID string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -127,7 +127,7 @@ func (h *ReplyHandler) Handle(ctx context.Context, content *MailContent, doer *u
 | 
				
			|||||||
				comment.Line,
 | 
									comment.Line,
 | 
				
			||||||
				content.Content,
 | 
									content.Content,
 | 
				
			||||||
				comment.TreePath,
 | 
									comment.TreePath,
 | 
				
			||||||
				false,
 | 
									false, // not pending review but a single review
 | 
				
			||||||
				comment.ReviewID,
 | 
									comment.ReviewID,
 | 
				
			||||||
				"",
 | 
									"",
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,7 +71,7 @@ func InvalidateCodeComments(ctx context.Context, prs issues_model.PullRequestLis
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateCodeComment creates a comment on the code line
 | 
					// CreateCodeComment creates a comment on the code line
 | 
				
			||||||
func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, line int64, content, treePath string, isReview bool, replyReviewID int64, latestCommitID string) (*issues_model.Comment, error) {
 | 
					func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, line int64, content, treePath string, pendingReview bool, replyReviewID int64, latestCommitID string) (*issues_model.Comment, error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		existsReview bool
 | 
							existsReview bool
 | 
				
			||||||
		err          error
 | 
							err          error
 | 
				
			||||||
@@ -82,7 +82,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.
 | 
				
			|||||||
	// - Comments that are part of a review
 | 
						// - Comments that are part of a review
 | 
				
			||||||
	// - Comments that reply to an existing review
 | 
						// - Comments that reply to an existing review
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !isReview && replyReviewID != 0 {
 | 
						if !pendingReview && replyReviewID != 0 {
 | 
				
			||||||
		// It's not part of a review; maybe a reply to a review comment or a single comment.
 | 
							// It's not part of a review; maybe a reply to a review comment or a single comment.
 | 
				
			||||||
		// Check if there are reviews for that line already; if there are, this is a reply
 | 
							// Check if there are reviews for that line already; if there are, this is a reply
 | 
				
			||||||
		if existsReview, err = issues_model.ReviewExists(issue, treePath, line); err != nil {
 | 
							if existsReview, err = issues_model.ReviewExists(issue, treePath, line); err != nil {
 | 
				
			||||||
@@ -91,7 +91,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Comments that are replies don't require a review header to show up in the issue view
 | 
						// Comments that are replies don't require a review header to show up in the issue view
 | 
				
			||||||
	if !isReview && existsReview {
 | 
						if !pendingReview && existsReview {
 | 
				
			||||||
		if err = issue.LoadRepo(ctx); err != nil {
 | 
							if err = issue.LoadRepo(ctx); err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -149,7 +149,7 @@ func CreateCodeComment(ctx context.Context, doer *user_model.User, gitRepo *git.
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !isReview && !existsReview {
 | 
						if !pendingReview && !existsReview {
 | 
				
			||||||
		// Submit the review we've just created so the comment shows up in the issue view
 | 
							// Submit the review we've just created so the comment shows up in the issue view
 | 
				
			||||||
		if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, issues_model.ReviewTypeComment, "", latestCommitID, nil); err != nil {
 | 
							if _, _, err = SubmitReview(ctx, doer, gitRepo, issue, issues_model.ReviewTypeComment, "", latestCommitID, nil); err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
{{if and $.root.SignedUserID (not $.Repository.IsArchived)}}
 | 
					{{if and $.root.SignedUserID (not $.Repository.IsArchived)}}
 | 
				
			||||||
	<form class="ui form {{if $.hidden}}gt-hidden comment-form comment-form-reply{{end}}" action="{{$.root.Issue.Link}}/files/reviews/comments" method="post">
 | 
						<form class="ui form {{if $.hidden}}gt-hidden comment-form{{end}}" action="{{$.root.Issue.Link}}/files/reviews/comments" method="post">
 | 
				
			||||||
	{{$.root.CsrfTokenHtml}}
 | 
						{{$.root.CsrfTokenHtml}}
 | 
				
			||||||
		<input type="hidden" name="origin" value="{{if $.root.PageIsPullFiles}}diff{{else}}timeline{{end}}">
 | 
							<input type="hidden" name="origin" value="{{if $.root.PageIsPullFiles}}diff{{else}}timeline{{end}}">
 | 
				
			||||||
		<input type="hidden" name="latest_commit_id" value="{{$.root.AfterCommitID}}"/>
 | 
							<input type="hidden" name="latest_commit_id" value="{{$.root.AfterCommitID}}"/>
 | 
				
			||||||
@@ -29,15 +29,10 @@
 | 
				
			|||||||
					<input type="hidden" name="reply" value="{{$.reply}}">
 | 
										<input type="hidden" name="reply" value="{{$.reply}}">
 | 
				
			||||||
				{{else}}
 | 
									{{else}}
 | 
				
			||||||
					{{if $.root.CurrentReview}}
 | 
										{{if $.root.CurrentReview}}
 | 
				
			||||||
						{{/* if there is only one "Add comment" button, the quick-submit should submit the form with is_review=true even if the "Add comment" button is not really clicked */}}
 | 
											<button name="pending_review" type="submit" class="ui submit green tiny button btn-add-comment">{{$.root.locale.Tr "repo.diff.comment.add_review_comment"}}</button>
 | 
				
			||||||
						<input type="hidden" name="is_review" value="true">
 | 
					 | 
				
			||||||
						<button name="is_review" value="true" type="submit"
 | 
					 | 
				
			||||||
								class="ui submit green tiny button btn-add-comment">{{$.root.locale.Tr "repo.diff.comment.add_review_comment"}}</button>
 | 
					 | 
				
			||||||
					{{else}}
 | 
										{{else}}
 | 
				
			||||||
						<button name="is_review" value="true" type="submit"
 | 
											<button name="pending_review" type="submit" class="ui submit green tiny button btn-start-review">{{$.root.locale.Tr "repo.diff.comment.start_review"}}</button>
 | 
				
			||||||
								class="ui submit green tiny button btn-start-review">{{$.root.locale.Tr "repo.diff.comment.start_review"}}</button>
 | 
											<button name="single_review" value="true" type="submit" class="ui submit tiny basic button btn-add-single">{{$.root.locale.Tr "repo.diff.comment.add_single_comment"}}</button>
 | 
				
			||||||
						<button type="submit"
 | 
					 | 
				
			||||||
								class="ui submit tiny basic button btn-add-single">{{$.root.locale.Tr "repo.diff.comment.add_single_comment"}}</button>
 | 
					 | 
				
			||||||
					{{end}}
 | 
										{{end}}
 | 
				
			||||||
				{{end}}
 | 
									{{end}}
 | 
				
			||||||
				{{if or (not $.HasComments) $.hidden}}
 | 
									{{if or (not $.HasComments) $.hidden}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,10 +11,8 @@ export function initRepoDiffReviewButton() {
 | 
				
			|||||||
  const $reviewBox = $('#review-box');
 | 
					  const $reviewBox = $('#review-box');
 | 
				
			||||||
  const $counter = $reviewBox.find('.review-comments-counter');
 | 
					  const $counter = $reviewBox.find('.review-comments-counter');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $(document).on('click', 'button[name="is_review"]', (e) => {
 | 
					  $(document).on('click', 'button[name="pending_review"]', (e) => {
 | 
				
			||||||
    const $form = $(e.target).closest('form');
 | 
					    const $form = $(e.target).closest('form');
 | 
				
			||||||
    $form.append('<input type="hidden" name="is_review" value="true">');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Watch for the form's submit event.
 | 
					    // Watch for the form's submit event.
 | 
				
			||||||
    $form.on('submit', () => {
 | 
					    $form.on('submit', () => {
 | 
				
			||||||
      const num = parseInt($counter.attr('data-pending-comment-number')) + 1 || 1;
 | 
					      const num = parseInt($counter.attr('data-pending-comment-number')) + 1 || 1;
 | 
				
			||||||
@@ -50,7 +48,15 @@ export function initRepoDiffConversationForm() {
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const formDataString = String(new URLSearchParams(new FormData($form[0])));
 | 
					    const formData = new FormData($form[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // if the form is submitted by a button, append the button's name and value to the form data
 | 
				
			||||||
 | 
					    const submitter = e.originalEvent?.submitter;
 | 
				
			||||||
 | 
					    const isSubmittedByButton = (submitter?.nodeName === 'BUTTON') || (submitter?.nodeName === 'INPUT' && submitter.type === 'submit');
 | 
				
			||||||
 | 
					    if (isSubmittedByButton && submitter.name) {
 | 
				
			||||||
 | 
					      formData.append(submitter.name, submitter.value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const formDataString = String(new URLSearchParams(formData));
 | 
				
			||||||
    const $newConversationHolder = $(await $.post($form.attr('action'), formDataString));
 | 
					    const $newConversationHolder = $(await $.post($form.attr('action'), formDataString));
 | 
				
			||||||
    const {path, side, idx} = $newConversationHolder.data();
 | 
					    const {path, side, idx} = $newConversationHolder.data();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -535,7 +535,7 @@ export function initRepoPullRequestReview() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const td = ntr.find(`.add-comment-${side}`);
 | 
					    const td = ntr.find(`.add-comment-${side}`);
 | 
				
			||||||
    let commentCloud = td.find('.comment-code-cloud');
 | 
					    let commentCloud = td.find('.comment-code-cloud');
 | 
				
			||||||
    if (commentCloud.length === 0 && !ntr.find('button[name="is_review"]').length) {
 | 
					    if (commentCloud.length === 0 && !ntr.find('button[name="pending_review"]').length) {
 | 
				
			||||||
      const data = await $.get($(this).closest('[data-new-comment-url]').data('new-comment-url'));
 | 
					      const data = await $.get($(this).closest('[data-new-comment-url]').data('new-comment-url'));
 | 
				
			||||||
      td.html(data);
 | 
					      td.html(data);
 | 
				
			||||||
      commentCloud = td.find('.comment-code-cloud');
 | 
					      commentCloud = td.find('.comment-code-cloud');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -963,10 +963,6 @@
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .comment-form-reply .footer {
 | 
					 | 
				
			||||||
          padding-bottom: 1em;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @media @mediaSm {
 | 
					        @media @mediaSm {
 | 
				
			||||||
          .ui.segments {
 | 
					          .ui.segments {
 | 
				
			||||||
            margin-left: -2rem;
 | 
					            margin-left: -2rem;
 | 
				
			||||||
@@ -3282,7 +3278,7 @@ td.blob-excerpt {
 | 
				
			|||||||
    position: sticky;
 | 
					    position: sticky;
 | 
				
			||||||
    top: 77px;
 | 
					    top: 77px;
 | 
				
			||||||
    z-index: 7;
 | 
					    z-index: 7;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    @media (max-width: 480px) {
 | 
					    @media (max-width: 480px) {
 | 
				
			||||||
      position: static;
 | 
					      position: static;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user