mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 15:04:00 +01:00 
			
		
		
		
	Merge fc4b73eac934a2931e153a44031ff5bb087c9197 into fe2599715730c385da38650903f3bc8400a4c919
This commit is contained in:
		
						commit
						49c0515d8d
					
				@ -559,6 +559,74 @@ func (issues IssueList) LoadDiscussComments(ctx context.Context) error {
 | 
			
		||||
	return issues.loadComments(ctx, builder.Eq{"comment.type": CommentTypeComment})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBlockedByCounts returns a map of issue ID to number of open issues that are blocking it
 | 
			
		||||
func (issues IssueList) GetBlockedByCount(ctx context.Context) (map[int64]int64, error) {
 | 
			
		||||
	type BlockedByCount struct {
 | 
			
		||||
		IssueID int64
 | 
			
		||||
		Count   int64
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bCounts := make([]*BlockedByCount, len(issues))
 | 
			
		||||
	ids := make([]int64, len(issues))
 | 
			
		||||
	for i, issue := range issues {
 | 
			
		||||
		ids[i] = issue.ID
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sess := db.GetEngine(ctx).In("issue_id", ids)
 | 
			
		||||
	err := sess.Select("issue_id, count(issue_dependency.id) as `count`").
 | 
			
		||||
		Join("INNER", "issue", "issue.id = issue_dependency.dependency_id").
 | 
			
		||||
		Where("is_closed = ?", false).
 | 
			
		||||
		GroupBy("issue_id").
 | 
			
		||||
		OrderBy("issue_id").
 | 
			
		||||
		Table("issue_dependency").
 | 
			
		||||
		Find(&bCounts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockedByCountMap := make(map[int64]int64, len(issues))
 | 
			
		||||
	for _, c := range bCounts {
 | 
			
		||||
		if c != nil {
 | 
			
		||||
			blockedByCountMap[c.IssueID] = c.Count
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return blockedByCountMap, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetBlockingCounts returns a map of issue ID to number of issues that are blocked by it
 | 
			
		||||
func (issues IssueList) GetBlockingCount(ctx context.Context) (map[int64]int64, error) {
 | 
			
		||||
	type BlockingCount struct {
 | 
			
		||||
		IssueID int64
 | 
			
		||||
		Count   int64
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bCounts := make([]*BlockingCount, 0, len(issues))
 | 
			
		||||
	ids := make([]int64, len(issues))
 | 
			
		||||
	for i, issue := range issues {
 | 
			
		||||
		ids[i] = issue.ID
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sess := db.GetEngine(ctx).In("dependency_id", ids)
 | 
			
		||||
	err := sess.Select("dependency_id as `issue_id`, count(id) as `count`").
 | 
			
		||||
		GroupBy("dependency_id").
 | 
			
		||||
		OrderBy("dependency_id").
 | 
			
		||||
		Table("issue_dependency").
 | 
			
		||||
		Find(&bCounts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockingCountMap := make(map[int64]int64, len(issues))
 | 
			
		||||
	for _, c := range bCounts {
 | 
			
		||||
		if c != nil {
 | 
			
		||||
			blockingCountMap[c.IssueID] = c.Count
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return blockingCountMap, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetApprovalCounts returns a map of issue ID to slice of approval counts
 | 
			
		||||
// FIXME: only returns official counts due to double counting of non-official approvals
 | 
			
		||||
func (issues IssueList) GetApprovalCounts(ctx context.Context) (map[int64][]*ReviewCount, error) {
 | 
			
		||||
 | 
			
		||||
@ -1806,6 +1806,10 @@ issues.dependency.add_error_dep_not_exist = Dependency does not exist.
 | 
			
		||||
issues.dependency.add_error_dep_exists = Dependency already exists.
 | 
			
		||||
issues.dependency.add_error_cannot_create_circular = You cannot create a dependency with two issues that block each other.
 | 
			
		||||
issues.dependency.add_error_dep_not_same_repo = Both issues must be in the same repository.
 | 
			
		||||
issues.dependency.blocking_count_1 = "This issue is blocking %d other issue."
 | 
			
		||||
issues.dependency.blocking_count_n = "This issue is blocking %d other issues."
 | 
			
		||||
issues.dependency.blocked_by_count_1 = "This issue is blocked by %d issue."
 | 
			
		||||
issues.dependency.blocked_by_count_n = "This issue is blocked by %d issues."
 | 
			
		||||
issues.review.self.approval = You cannot approve your own pull request.
 | 
			
		||||
issues.review.self.rejection = You cannot request changes on your own pull request.
 | 
			
		||||
issues.review.approve = "approved these changes %s"
 | 
			
		||||
 | 
			
		||||
@ -654,6 +654,18 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID, projectID int6
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockingCounts, err := issues.GetBlockingCount(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("BlockingCounts", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockedByCounts, err := issues.GetBlockedByCount(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("BlockedByCounts", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ctx.IsSigned {
 | 
			
		||||
		if err := issues.LoadIsRead(ctx, ctx.Doer.ID); err != nil {
 | 
			
		||||
			ctx.ServerError("LoadIsRead", err)
 | 
			
		||||
@ -718,6 +730,21 @@ func prepareIssueFilterAndList(ctx *context.Context, milestoneID, projectID int6
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.Data["BlockingCounts"] = func(issueID int64) int64 {
 | 
			
		||||
		counts, ok := blockingCounts[issueID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0
 | 
			
		||||
		}
 | 
			
		||||
		return counts
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["BlockedByCounts"] = func(issueID int64) int64 {
 | 
			
		||||
		counts, ok := blockedByCounts[issueID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0
 | 
			
		||||
		}
 | 
			
		||||
		return counts
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	retrieveProjectsForIssueList(ctx, repo)
 | 
			
		||||
	if ctx.Written() {
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
@ -627,6 +627,33 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
 | 
			
		||||
		}
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockingCounts, err := issues.GetBlockingCount(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("BlockingCounts", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockedByCounts, err := issues.GetBlockedByCount(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("BlockedByCounts", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["BlockingCounts"] = func(issueID int64) int64 {
 | 
			
		||||
		counts, ok := blockingCounts[issueID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0
 | 
			
		||||
		}
 | 
			
		||||
		return counts
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["BlockedByCounts"] = func(issueID int64) int64 {
 | 
			
		||||
		counts, ok := blockedByCounts[issueID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0
 | 
			
		||||
		}
 | 
			
		||||
		return counts
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.Data["CommitLastStatus"] = lastStatus
 | 
			
		||||
	ctx.Data["CommitStatuses"] = commitStatuses
 | 
			
		||||
	ctx.Data["IssueStats"] = issueStats
 | 
			
		||||
 | 
			
		||||
@ -279,6 +279,32 @@ func NotificationSubscriptions(ctx *context.Context) {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockingCounts, err := issues.GetBlockingCount(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("BlockingCounts", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	blockedByCounts, err := issues.GetBlockedByCount(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.ServerError("BlockedByCounts", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["BlockingCounts"] = func(issueID int64) int64 {
 | 
			
		||||
		counts, ok := blockingCounts[issueID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0
 | 
			
		||||
		}
 | 
			
		||||
		return counts
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["BlockedByCounts"] = func(issueID int64) int64 {
 | 
			
		||||
		counts, ok := blockedByCounts[issueID]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0
 | 
			
		||||
		}
 | 
			
		||||
		return counts
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.Data["Status"] = 1
 | 
			
		||||
	ctx.Data["Title"] = ctx.Tr("notification.subscriptions")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,10 @@
 | 
			
		||||
<div id="issue-list" class="flex-list">
 | 
			
		||||
	{{$approvalCounts := .ApprovalCounts}}
 | 
			
		||||
	{{$blockedByCounts := .BlockedByCounts}}
 | 
			
		||||
	{{$blockingCounts := .BlockingCounts}}
 | 
			
		||||
	{{range .Issues}}
 | 
			
		||||
		{{$blockedByCount := call $blockedByCounts .ID}}
 | 
			
		||||
		{{$blockingCount := call $blockingCounts .ID}}
 | 
			
		||||
		<div class="flex-item">
 | 
			
		||||
 | 
			
		||||
			<div class="flex-item-leading">
 | 
			
		||||
@ -22,6 +26,22 @@
 | 
			
		||||
								{{template "repo/commit_statuses" dict "Status" (index $.CommitLastStatus .PullRequest.ID) "Statuses" (index $.CommitStatuses .PullRequest.ID)}}
 | 
			
		||||
							{{end}}
 | 
			
		||||
						{{end}}
 | 
			
		||||
						{{if gt $blockedByCount 0}}
 | 
			
		||||
							<div class="ui label label-blocking">
 | 
			
		||||
								<span data-tooltip-content="{{ctx.Locale.TrN $blockedByCount "repo.issues.dependency.blocked_by_count_1" "repo.issues.dependency.blocked_by_count_n" $blockedByCount}}" class="text red flex-text-block">
 | 
			
		||||
									{{svg "octicon-blocked" 16}}
 | 
			
		||||
									{{$blockedByCount}}
 | 
			
		||||
								</span>
 | 
			
		||||
							</div>
 | 
			
		||||
						{{end}}
 | 
			
		||||
						{{if and (gt $blockingCount 0) (not .IsClosed)}}
 | 
			
		||||
							<div class="ui label label-blocking">
 | 
			
		||||
								<span data-tooltip-content="{{ctx.Locale.TrN $blockingCount "repo.issues.dependency.blocking_count_1" "repo.issues.dependency.blocking_count_n" $blockingCount}}" class="text red flex-text-block">
 | 
			
		||||
									{{svg "octicon-report" 16}}
 | 
			
		||||
									{{$blockingCount}}
 | 
			
		||||
								</span>
 | 
			
		||||
							</div>
 | 
			
		||||
						{{end}}
 | 
			
		||||
						<span class="labels-list">
 | 
			
		||||
							{{range .Labels}}
 | 
			
		||||
								<a href="?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}{{if ne $.listType "milestone"}}&milestone={{$.MilestoneID}}{{end}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}{{if $.ShowArchivedLabels}}&archived=true{{end}}">{{ctx.RenderUtils.RenderLabel .}}</a>
 | 
			
		||||
 | 
			
		||||
@ -56,3 +56,10 @@
 | 
			
		||||
  top: 10px;
 | 
			
		||||
  right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.label-blocking {
 | 
			
		||||
  border: 1px solid var(--color-secondary) !important;
 | 
			
		||||
  background: none transparent !important;
 | 
			
		||||
  margin-left: 1px;
 | 
			
		||||
  margin-right: 1px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user