mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 00:02:59 -04:00 
			
		
		
		
	Bug fixes for Issues filters (#413)
Correctly handle simultaneous assignee/poster filters, and conflicting assignee filters
This commit is contained in:
		
							parent
							
								
									8a4161c723
								
							
						
					
					
						commit
						d0932ef147
					
				| @ -855,15 +855,14 @@ func GetIssueByID(id int64) (*Issue, error) { | ||||
| 
 | ||||
| // IssuesOptions represents options of an issue. | ||||
| type IssuesOptions struct { | ||||
| 	UserID      int64 | ||||
| 	AssigneeID  int64 | ||||
| 	RepoID      int64 | ||||
| 	AssigneeID  int64 | ||||
| 	PosterID    int64 | ||||
| 	MentionedID int64 | ||||
| 	MilestoneID int64 | ||||
| 	RepoIDs     []int64 | ||||
| 	Page        int | ||||
| 	IsClosed    bool | ||||
| 	IsMention   bool | ||||
| 	IsPull      bool | ||||
| 	Labels      string | ||||
| 	SortType    string | ||||
| @ -887,10 +886,18 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) { | ||||
| 
 | ||||
| 	if opts.AssigneeID > 0 { | ||||
| 		sess.And("issue.assignee_id=?", opts.AssigneeID) | ||||
| 	} else if opts.PosterID > 0 { | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.PosterID > 0 { | ||||
| 		sess.And("issue.poster_id=?", opts.PosterID) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.MentionedID > 0 { | ||||
| 		sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | ||||
| 			And("issue_user.is_mentioned = ?", true). | ||||
| 			And("issue_user.uid = ?", opts.MentionedID) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.MilestoneID > 0 { | ||||
| 		sess.And("issue.milestone_id=?", opts.MilestoneID) | ||||
| 	} | ||||
| @ -926,16 +933,6 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.IsMention { | ||||
| 		sess. | ||||
| 			Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | ||||
| 			And("issue_user.is_mentioned = ?", true) | ||||
| 
 | ||||
| 		if opts.UserID > 0 { | ||||
| 			sess.And("issue_user.uid = ?", opts.UserID) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	issues := make([]*Issue, 0, setting.UI.IssuePagingNum) | ||||
| 	if err := sess.Find(&issues); err != nil { | ||||
| 		return nil, fmt.Errorf("Find: %v", err) | ||||
| @ -1156,11 +1153,11 @@ func parseCountResult(results []map[string][]byte) int64 { | ||||
| // IssueStatsOptions contains parameters accepted by GetIssueStats. | ||||
| type IssueStatsOptions struct { | ||||
| 	RepoID      int64 | ||||
| 	UserID      int64 | ||||
| 	Labels      string | ||||
| 	MilestoneID int64 | ||||
| 	AssigneeID  int64 | ||||
| 	FilterMode  int | ||||
| 	MentionedID int64 | ||||
| 	PosterID    int64 | ||||
| 	IsPull      bool | ||||
| } | ||||
| 
 | ||||
| @ -1191,43 +1188,25 @@ func GetIssueStats(opts *IssueStatsOptions) *IssueStats { | ||||
| 			sess.And("assignee_id = ?", opts.AssigneeID) | ||||
| 		} | ||||
| 
 | ||||
| 		if opts.PosterID > 0 { | ||||
| 			sess.And("poster_id = ?", opts.PosterID) | ||||
| 		} | ||||
| 
 | ||||
| 		if opts.MentionedID > 0 { | ||||
| 			sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | ||||
| 			And("issue_user.uid = ?", opts.MentionedID). | ||||
| 			And("issue_user.is_mentioned = ?", true) | ||||
| 		} | ||||
| 
 | ||||
| 		return sess | ||||
| 	} | ||||
| 
 | ||||
| 	switch opts.FilterMode { | ||||
| 	case FilterModeAll, FilterModeAssign: | ||||
| 		stats.OpenCount, _ = countSession(opts). | ||||
| 			And("is_closed = ?", false). | ||||
| 			Count(&Issue{}) | ||||
| 
 | ||||
| 		stats.ClosedCount, _ = countSession(opts). | ||||
| 			And("is_closed = ?", true). | ||||
| 			Count(&Issue{}) | ||||
| 	case FilterModeCreate: | ||||
| 		stats.OpenCount, _ = countSession(opts). | ||||
| 			And("poster_id = ?", opts.UserID). | ||||
| 			And("is_closed = ?", false). | ||||
| 			Count(&Issue{}) | ||||
| 
 | ||||
| 		stats.ClosedCount, _ = countSession(opts). | ||||
| 			And("poster_id = ?", opts.UserID). | ||||
| 			And("is_closed = ?", true). | ||||
| 			Count(&Issue{}) | ||||
| 	case FilterModeMention: | ||||
| 		stats.OpenCount, _ = countSession(opts). | ||||
| 			Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | ||||
| 			And("issue_user.uid = ?", opts.UserID). | ||||
| 			And("issue_user.is_mentioned = ?", true). | ||||
| 			And("issue.is_closed = ?", false). | ||||
| 			Count(&Issue{}) | ||||
| 
 | ||||
| 		stats.ClosedCount, _ = countSession(opts). | ||||
| 			Join("INNER", "issue_user", "issue.id = issue_user.issue_id"). | ||||
| 			And("issue_user.uid = ?", opts.UserID). | ||||
| 			And("issue_user.is_mentioned = ?", true). | ||||
| 			And("issue.is_closed = ?", true). | ||||
| 			Count(&Issue{}) | ||||
| 	} | ||||
| 	stats.OpenCount, _ = countSession(opts). | ||||
| 		And("is_closed = ?", false). | ||||
| 		Count(&Issue{}) | ||||
| 	stats.ClosedCount, _ = countSession(opts). | ||||
| 		And("is_closed = ?", true). | ||||
| 		Count(&Issue{}) | ||||
| 	return stats | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -130,38 +130,42 @@ func Issues(ctx *context.Context) { | ||||
| 
 | ||||
| 	var ( | ||||
| 		assigneeID = ctx.QueryInt64("assignee") | ||||
| 		posterID   int64 | ||||
| 		posterID     int64 | ||||
| 		mentionedID  int64 | ||||
| 		forceEmpty   bool | ||||
| 	) | ||||
| 	filterMode := models.FilterModeAll | ||||
| 	switch viewType { | ||||
| 	case "assigned": | ||||
| 		filterMode = models.FilterModeAssign | ||||
| 		assigneeID = ctx.User.ID | ||||
| 		if assigneeID > 0 && ctx.User.ID != assigneeID { | ||||
| 			// two different assignees, must be empty | ||||
| 			forceEmpty = true | ||||
| 		} else { | ||||
| 			assigneeID = ctx.User.ID | ||||
| 		} | ||||
| 	case "created_by": | ||||
| 		filterMode = models.FilterModeCreate | ||||
| 		posterID = ctx.User.ID | ||||
| 	case "mentioned": | ||||
| 		filterMode = models.FilterModeMention | ||||
| 	} | ||||
| 
 | ||||
| 	var uid int64 = -1 | ||||
| 	if ctx.IsSigned { | ||||
| 		uid = ctx.User.ID | ||||
| 		mentionedID = ctx.User.ID | ||||
| 	} | ||||
| 
 | ||||
| 	repo := ctx.Repo.Repository | ||||
| 	selectLabels := ctx.Query("labels") | ||||
| 	milestoneID := ctx.QueryInt64("milestone") | ||||
| 	isShowClosed := ctx.Query("state") == "closed" | ||||
| 	issueStats := models.GetIssueStats(&models.IssueStatsOptions{ | ||||
| 		RepoID:      repo.ID, | ||||
| 		UserID:      uid, | ||||
| 		Labels:      selectLabels, | ||||
| 		MilestoneID: milestoneID, | ||||
| 		AssigneeID:  assigneeID, | ||||
| 		FilterMode:  filterMode, | ||||
| 		IsPull:      isPullList, | ||||
| 	}) | ||||
| 
 | ||||
| 	var issueStats *models.IssueStats | ||||
| 	if forceEmpty { | ||||
| 		issueStats = &models.IssueStats{} | ||||
| 	} else { | ||||
| 		issueStats = models.GetIssueStats(&models.IssueStatsOptions{ | ||||
| 			RepoID:      repo.ID, | ||||
| 			Labels:      selectLabels, | ||||
| 			MilestoneID: milestoneID, | ||||
| 			AssigneeID:  assigneeID, | ||||
| 			MentionedID: mentionedID, | ||||
| 			IsPull:      isPullList, | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	page := ctx.QueryInt("page") | ||||
| 	if page <= 1 { | ||||
| @ -177,22 +181,28 @@ func Issues(ctx *context.Context) { | ||||
| 	pager := paginater.New(total, setting.UI.IssuePagingNum, page, 5) | ||||
| 	ctx.Data["Page"] = pager | ||||
| 
 | ||||
| 	issues, err := models.Issues(&models.IssuesOptions{ | ||||
| 		UserID:      uid, | ||||
| 		AssigneeID:  assigneeID, | ||||
| 		RepoID:      repo.ID, | ||||
| 		PosterID:    posterID, | ||||
| 		MilestoneID: milestoneID, | ||||
| 		Page:        pager.Current(), | ||||
| 		IsClosed:    isShowClosed, | ||||
| 		IsMention:   filterMode == models.FilterModeMention, | ||||
| 		IsPull:      isPullList, | ||||
| 		Labels:      selectLabels, | ||||
| 		SortType:    sortType, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(500, "Issues", err) | ||||
| 		return | ||||
| 
 | ||||
| 	var issues []*models.Issue | ||||
| 	if forceEmpty { | ||||
| 		issues = []*models.Issue{} | ||||
| 	} else { | ||||
| 		var err error | ||||
| 		issues, err = models.Issues(&models.IssuesOptions{ | ||||
| 			AssigneeID:  assigneeID, | ||||
| 			RepoID:      repo.ID, | ||||
| 			PosterID:    posterID, | ||||
| 			MentionedID: mentionedID, | ||||
| 			MilestoneID: milestoneID, | ||||
| 			Page:        pager.Current(), | ||||
| 			IsClosed:    isShowClosed, | ||||
| 			IsPull:      isPullList, | ||||
| 			Labels:      selectLabels, | ||||
| 			SortType:    sortType, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			ctx.Handle(500, "Issues", err) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Get issue-user relations. | ||||
| @ -233,7 +243,7 @@ func Issues(ctx *context.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if viewType == "assigned" { | ||||
| 	if ctx.QueryInt64("assignee") == 0 { | ||||
| 		assigneeID = 0 // Reset ID to prevent unexpected selection of assignee. | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -272,7 +272,6 @@ func Issues(ctx *context.Context) { | ||||
| 
 | ||||
| 	// Get issues. | ||||
| 	issues, err := models.Issues(&models.IssuesOptions{ | ||||
| 		UserID:     ctxUser.ID, | ||||
| 		AssigneeID: assigneeID, | ||||
| 		RepoID:     repoID, | ||||
| 		PosterID:   posterID, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user