Improve reviewing PR UX (#19612)
This commit is contained in:
parent
5a9c505e14
commit
0eac09e066
7 changed files with 74 additions and 3 deletions
|
@ -752,11 +752,27 @@ func ViewPullFiles(ctx *context.Context) {
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Data["CurrentReview"], err = models.GetCurrentReview(ctx.Doer, issue)
|
|
||||||
|
currentReview, err := models.GetCurrentReview(ctx.Doer, issue)
|
||||||
if err != nil && !models.IsErrReviewNotExist(err) {
|
if err != nil && !models.IsErrReviewNotExist(err) {
|
||||||
ctx.ServerError("GetCurrentReview", err)
|
ctx.ServerError("GetCurrentReview", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
numPendingCodeComments := int64(0)
|
||||||
|
if currentReview != nil {
|
||||||
|
numPendingCodeComments, err = models.CountComments(&models.FindCommentsOptions{
|
||||||
|
Type: models.CommentTypeCode,
|
||||||
|
ReviewID: currentReview.ID,
|
||||||
|
IssueID: issue.ID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("CountComments", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Data["CurrentReview"] = currentReview
|
||||||
|
ctx.Data["PendingCodeCommentNumber"] = numPendingCodeComments
|
||||||
|
|
||||||
getBranchData(ctx, issue)
|
getBranchData(ctx, issue)
|
||||||
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID)
|
ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID)
|
||||||
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
|
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<div class="comment-header-right actions df ac">
|
<div class="comment-header-right actions df ac">
|
||||||
{{if and .Review}}
|
{{if and .Review}}
|
||||||
{{if eq .Review.Type 0}}
|
{{if eq .Review.Type 0}}
|
||||||
<div class="ui label basic small yellow">
|
<div class="ui label basic small yellow pending-label">
|
||||||
{{$.root.i18n.Tr "repo.issues.review.pending"}}
|
{{$.root.i18n.Tr "repo.issues.review.pending"}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<div class="ui top right pointing dropdown custom" id="review-box">
|
<div class="ui top right pointing dropdown custom" id="review-box">
|
||||||
<div class="ui tiny green button btn-review">
|
<div class="ui tiny green button btn-review">
|
||||||
{{.i18n.Tr "repo.diff.review"}}
|
{{.i18n.Tr "repo.diff.review"}}
|
||||||
|
<span class="ui small label review-comments-counter" data-pending-comment-number="{{.PendingCodeCommentNumber}}">{{.PendingCodeCommentNumber}}</span>
|
||||||
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="menu review-box">
|
<div class="menu review-box">
|
||||||
|
|
|
@ -6,8 +6,23 @@ import {validateTextareaNonEmpty} from './comp/EasyMDE.js';
|
||||||
const {csrfToken} = window.config;
|
const {csrfToken} = window.config;
|
||||||
|
|
||||||
export function initRepoDiffReviewButton() {
|
export function initRepoDiffReviewButton() {
|
||||||
|
const $reviewBox = $('#review-box');
|
||||||
|
const $counter = $reviewBox.find('.review-comments-counter');
|
||||||
|
|
||||||
$(document).on('click', 'button[name="is_review"]', (e) => {
|
$(document).on('click', 'button[name="is_review"]', (e) => {
|
||||||
$(e.target).closest('form').append('<input type="hidden" name="is_review" value="true">');
|
const $form = $(e.target).closest('form');
|
||||||
|
$form.append('<input type="hidden" name="is_review" value="true">');
|
||||||
|
|
||||||
|
// Watch for the form's submit event.
|
||||||
|
$form.on('submit', () => {
|
||||||
|
const num = parseInt($counter.attr('data-pending-comment-number')) + 1 || 1;
|
||||||
|
$counter.attr('data-pending-comment-number', num);
|
||||||
|
$counter.text(num);
|
||||||
|
// Force the browser to reflow the DOM. This is to ensure that the browser replay the animation
|
||||||
|
$reviewBox.removeClass('pulse');
|
||||||
|
$reviewBox.width();
|
||||||
|
$reviewBox.addClass('pulse');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,16 @@ export function initRepoIssueCommentDelete() {
|
||||||
_csrf: csrfToken,
|
_csrf: csrfToken,
|
||||||
}).done(() => {
|
}).done(() => {
|
||||||
const $conversationHolder = $this.closest('.conversation-holder');
|
const $conversationHolder = $this.closest('.conversation-holder');
|
||||||
|
|
||||||
|
// Check if this was a pending comment.
|
||||||
|
if ($conversationHolder.find('.pending-label').length) {
|
||||||
|
const $counter = $('#review-box .review-comments-counter');
|
||||||
|
let num = parseInt($counter.attr('data-pending-comment-number')) - 1 || 0;
|
||||||
|
num = Math.max(num, 0);
|
||||||
|
$counter.attr('data-pending-comment-number', num);
|
||||||
|
$counter.text(num);
|
||||||
|
}
|
||||||
|
|
||||||
$(`#${$this.data('comment-id')}`).remove();
|
$(`#${$this.data('comment-id')}`).remove();
|
||||||
if ($conversationHolder.length && !$conversationHolder.find('.comment').length) {
|
if ($conversationHolder.length && !$conversationHolder.find('.comment').length) {
|
||||||
const path = $conversationHolder.data('path');
|
const path = $conversationHolder.data('path');
|
||||||
|
|
|
@ -242,6 +242,19 @@ a.blob-excerpt:hover {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#review-box .review-comments-counter {
|
||||||
|
background-color: var(--color-primary-light-4);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#review-box:hover .review-comments-counter {
|
||||||
|
background-color: var(--color-primary-light-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#review-box .review-comments-counter[data-pending-comment-number="0"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.pull.files.diff [id] {
|
.pull.files.diff [id] {
|
||||||
scroll-margin-top: 99px;
|
scroll-margin-top: 99px;
|
||||||
|
|
||||||
|
|
|
@ -50,3 +50,19 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.8);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse {
|
||||||
|
animation: pulse 2s linear;
|
||||||
|
}
|
||||||
|
|
Reference in a new issue