From d0932ef1473b9ce27474ccf24acfca106dd93fec Mon Sep 17 00:00:00 2001 From: Ethan Koenig Date: Sat, 24 Dec 2016 05:33:21 -0500 Subject: [PATCH] Bug fixes for Issues filters (#413) Correctly handle simultaneous assignee/poster filters, and conflicting assignee filters --- models/issue.go | 79 +++++++++++++++------------------------- routers/repo/issue.go | 84 ++++++++++++++++++++++++------------------- routers/user/home.go | 1 - 3 files changed, 76 insertions(+), 88 deletions(-) diff --git a/models/issue.go b/models/issue.go index 13d27b22c6..57490bbc5b 100644 --- a/models/issue.go +++ b/models/issue.go @@ -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 } diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 343b93e273..14c1ea1aa7 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -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. } diff --git a/routers/user/home.go b/routers/user/home.go index 513dd9ce06..571849df30 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -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,