Skip to content

Commit 80db442

Browse files
authored
Add Approval Counts to pulls list (#10238)
* Add Approval Counts to pulls list Add simple approvals counts to pulls lists * Remove non-official counts * Add PR features to milestone_issues.tmpl
1 parent f422a11 commit 80db442

File tree

8 files changed

+154
-4
lines changed

8 files changed

+154
-4
lines changed

models/issue_list.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,3 +515,37 @@ func (issues IssueList) LoadComments() error {
515515
func (issues IssueList) LoadDiscussComments() error {
516516
return issues.loadComments(x, builder.Eq{"comment.type": CommentTypeComment})
517517
}
518+
519+
// GetApprovalCounts returns a map of issue ID to slice of approval counts
520+
// FIXME: only returns official counts due to double counting of non-official approvals
521+
func (issues IssueList) GetApprovalCounts() (map[int64][]*ReviewCount, error) {
522+
return issues.getApprovalCounts(x)
523+
}
524+
525+
func (issues IssueList) getApprovalCounts(e Engine) (map[int64][]*ReviewCount, error) {
526+
rCounts := make([]*ReviewCount, 0, 6*len(issues))
527+
ids := make([]int64, len(issues))
528+
for i, issue := range issues {
529+
ids[i] = issue.ID
530+
}
531+
sess := e.In("issue_id", ids)
532+
err := sess.Select("issue_id, type, count(id) as `count`").Where("official = ?", true).GroupBy("issue_id, type").OrderBy("issue_id").Table("review").Find(&rCounts)
533+
if err != nil {
534+
return nil, err
535+
}
536+
537+
approvalCountMap := make(map[int64][]*ReviewCount, len(issues))
538+
if len(rCounts) > 0 {
539+
start := 0
540+
lastID := rCounts[0].IssueID
541+
for i, current := range rCounts[1:] {
542+
if lastID != current.IssueID {
543+
approvalCountMap[lastID] = rCounts[start:i]
544+
start = i
545+
lastID = current.IssueID
546+
}
547+
}
548+
approvalCountMap[lastID] = rCounts[start:]
549+
}
550+
return approvalCountMap, nil
551+
}

models/pull.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,25 @@ func (pr *PullRequest) GetCommitMessages() string {
352352
return stringBuilder.String()
353353
}
354354

355+
// ReviewCount represents a count of Reviews
356+
type ReviewCount struct {
357+
IssueID int64
358+
Type ReviewType
359+
Count int64
360+
}
361+
362+
// GetApprovalCounts returns the approval counts by type
363+
// FIXME: Only returns official counts due to double counting of non-official counts
364+
func (pr *PullRequest) GetApprovalCounts() ([]*ReviewCount, error) {
365+
return pr.getApprovalCounts(x)
366+
}
367+
368+
func (pr *PullRequest) getApprovalCounts(e Engine) ([]*ReviewCount, error) {
369+
rCounts := make([]*ReviewCount, 0, 6)
370+
sess := e.Where("issue_id = ?", pr.IssueID)
371+
return rCounts, sess.Select("issue_id, type, count(id) as `count`").Where("official = ?", true).GroupBy("issue_id, type").Table("review").Find(&rCounts)
372+
}
373+
355374
// GetApprovers returns the approvers of the pull request
356375
func (pr *PullRequest) GetApprovers() string {
357376

options/locale/locale_en-US.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,11 @@ pulls.cannot_auto_merge_desc = This pull request cannot be merged automatically
10821082
pulls.cannot_auto_merge_helper = Merge manually to resolve the conflicts.
10831083
pulls.num_conflicting_files_1 = "%d conflicting file"
10841084
pulls.num_conflicting_files_n = "%d conflicting files"
1085+
pulls.approve_count_1 = "%d approval"
1086+
pulls.approve_count_n = "%d approvals"
1087+
pulls.reject_count_1 = "%d change request"
1088+
pulls.reject_count_n = "%d change requests"
1089+
10851090
pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled.
10861091
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
10871092
pulls.no_merge_wip = This pull request can not be merged because it is marked as being a work in progress.

routers/repo/issue.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,12 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
216216
}
217217
}
218218

219+
approvalCounts, err := models.IssueList(issues).GetApprovalCounts()
220+
if err != nil {
221+
ctx.ServerError("ApprovalCounts", err)
222+
return
223+
}
224+
219225
var commitStatus = make(map[int64]*models.CommitStatus, len(issues))
220226

221227
// Get posters.
@@ -263,6 +269,22 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
263269
assigneeID = 0 // Reset ID to prevent unexpected selection of assignee.
264270
}
265271

272+
ctx.Data["ApprovalCounts"] = func(issueID int64, typ string) int64 {
273+
counts, ok := approvalCounts[issueID]
274+
if !ok || len(counts) == 0 {
275+
return 0
276+
}
277+
reviewTyp := models.ReviewTypeApprove
278+
if typ == "reject" {
279+
reviewTyp = models.ReviewTypeReject
280+
}
281+
for _, count := range counts {
282+
if count.Type == reviewTyp {
283+
return count.Count
284+
}
285+
}
286+
return 0
287+
}
266288
ctx.Data["IssueStats"] = issueStats
267289
ctx.Data["SelLabelIDs"] = labelIDs
268290
ctx.Data["SelectLabels"] = selectLabels

routers/user/home.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,12 @@ func Issues(ctx *context.Context) {
528528
issues = []*models.Issue{}
529529
}
530530

531+
approvalCounts, err := models.IssueList(issues).GetApprovalCounts()
532+
if err != nil {
533+
ctx.ServerError("ApprovalCounts", err)
534+
return
535+
}
536+
531537
showReposMap := make(map[int64]*models.Repository, len(counts))
532538
for repoID := range counts {
533539
if repoID > 0 {
@@ -639,6 +645,22 @@ func Issues(ctx *context.Context) {
639645
}
640646

641647
ctx.Data["Issues"] = issues
648+
ctx.Data["ApprovalCounts"] = func(issueID int64, typ string) int64 {
649+
counts, ok := approvalCounts[issueID]
650+
if !ok || len(counts) == 0 {
651+
return 0
652+
}
653+
reviewTyp := models.ReviewTypeApprove
654+
if typ == "reject" {
655+
reviewTyp = models.ReviewTypeReject
656+
}
657+
for _, count := range counts {
658+
if count.Type == reviewTyp {
659+
return count.Count
660+
}
661+
}
662+
return 0
663+
}
642664
ctx.Data["CommitStatus"] = commitStatus
643665
ctx.Data["Repos"] = showRepos
644666
ctx.Data["Counts"] = counts

templates/repo/issue/list.tmpl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
</div>
203203

204204
<div class="issue list">
205+
{{ $approvalCounts := .ApprovalCounts}}
205206
{{range .Issues}}
206207
<li class="item">
207208
{{if $.CanWriteIssuesOrPulls}}
@@ -268,6 +269,16 @@
268269
</a>
269270
{{end}}
270271
{{if .IsPull}}
272+
{{$approveOfficial := call $approvalCounts .ID "approve"}}
273+
{{$rejectOfficial := call $approvalCounts .ID "reject"}}
274+
{{if or (gt $approveOfficial 0) (gt $rejectOfficial 0)}}
275+
<span class="approvals">{{svg "octicon-check" 16}}
276+
{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
277+
{{if or (gt $rejectOfficial 0)}}
278+
<span class="rejects">{{svg "octicon-x" 16}}
279+
{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
280+
{{end}}
281+
{{end}}
271282
{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
272283
<span class="conflicting">{{svg "octicon-mirror" 16}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}}</span>
273284
{{end}}

templates/repo/issue/milestone_issues.tmpl

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@
177177
</div>
178178

179179
<div class="issue list">
180+
{{ $approvalCounts := .ApprovalCounts}}
180181
{{range .Issues}}
181182
{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
182183
<li class="item">
@@ -185,9 +186,15 @@
185186
<input type="checkbox" data-issue-id={{.ID}}></input>
186187
</div>
187188
{{end}}
188-
<div class="ui {{if .IsRead}}gray{{else}}green{{end}} label">#{{.Index}}</div>
189+
<div class="ui {{if .IsClosed}}{{if .IsPull}}{{if .PullRequest.HasMerged}}purple{{else}}red{{end}}{{else}}red{{end}}{{else}}{{if .IsRead}}white{{else}}green{{end}}{{end}} label">#{{.Index}}</div>
189190
<a class="title has-emoji" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Title}}</a>
190191

192+
{{if .IsPull }}
193+
{{if (index $.CommitStatus .PullRequest.ID)}}
194+
{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
195+
{{end}}
196+
{{end}}
197+
191198
{{range .Labels}}
192199
<a class="ui label has-emoji" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}" title="{{.Description}}">{{.Name}}</a>
193200
{{end}}
@@ -201,11 +208,15 @@
201208
{{end}}
202209

203210
<p class="desc">
204-
{{if gt .Poster.ID 0}}
205-
{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName|Escape) | Safe}}
211+
{{ $timeStr := TimeSinceUnix .GetLastEventTimestamp $.Lang }}
212+
{{if .OriginalAuthor }}
213+
{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
214+
{{else if gt .Poster.ID 0}}
215+
{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName | Escape) | Safe}}
206216
{{else}}
207-
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName|Escape) | Safe}}
217+
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
208218
{{end}}
219+
209220
{{if .Ref}}
210221
<a class="ref" href="{{$.RepoLink}}/src/branch/{{.Ref}}">
211222
{{svg "octicon-git-branch" 16}} {{.Ref}}
@@ -227,6 +238,21 @@
227238
<img class="ui avatar image" src="{{.RelAvatarLink}}">
228239
</a>
229240
{{end}}
241+
{{if .IsPull}}
242+
{{$approveOfficial := call $approvalCounts .ID "approve"}}
243+
{{$rejectOfficial := call $approvalCounts .ID "reject"}}
244+
{{if or (gt $approveOfficial 0) (gt $rejectOfficial 0)}}
245+
<span class="approvals">{{svg "octicon-check" 16}}
246+
{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
247+
{{if or (gt $rejectOfficial 0)}}
248+
<span class="rejects">{{svg "octicon-x" 16}}
249+
{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
250+
{{end}}
251+
{{end}}
252+
{{if and (not .PullRequest.HasMerged) ((len .PullRequest.ConflictedFiles) gt 0)}}
253+
<span class="conflicting">{{svg "octicon-mirror" 16}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}}</span>
254+
{{end}}
255+
{{end}}
230256
</p>
231257
</li>
232258
{{end}}

templates/user/dashboard/issues.tmpl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
</div>
102102

103103
<div class="issue list">
104+
{{ $approvalCounts := .ApprovalCounts}}
104105
{{range .Issues}}
105106

106107
{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
@@ -170,6 +171,16 @@
170171
</span>
171172
{{end}}
172173
{{if .IsPull}}
174+
{{$approveOfficial := call $approvalCounts .ID "approve"}}
175+
{{$rejectOfficial := call $approvalCounts .ID "reject"}}
176+
{{if or (gt $approveOfficial 0) (gt $rejectOfficial 0) }}
177+
<span class="approvals">{{svg "octicon-check" 16}}
178+
{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
179+
{{if or (gt $rejectOfficial 0)}}
180+
<span class="rejects">{{svg "octicon-x" 16}}
181+
{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
182+
{{end}}
183+
{{end}}
173184
{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
174185
<span class="conflicting">{{svg "octicon-mirror" 16}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}}</span>
175186
{{end}}

0 commit comments

Comments
 (0)