Skip to content

Commit d0932ef

Browse files
ethantkoeniglunny
authored andcommitted
Bug fixes for Issues filters (#413)
Correctly handle simultaneous assignee/poster filters, and conflicting assignee filters
1 parent 8a4161c commit d0932ef

File tree

3 files changed

+76
-88
lines changed

3 files changed

+76
-88
lines changed

models/issue.go

+29-50
Original file line numberDiff line numberDiff line change
@@ -855,15 +855,14 @@ func GetIssueByID(id int64) (*Issue, error) {
855855

856856
// IssuesOptions represents options of an issue.
857857
type IssuesOptions struct {
858-
UserID int64
859-
AssigneeID int64
860858
RepoID int64
859+
AssigneeID int64
861860
PosterID int64
861+
MentionedID int64
862862
MilestoneID int64
863863
RepoIDs []int64
864864
Page int
865865
IsClosed bool
866-
IsMention bool
867866
IsPull bool
868867
Labels string
869868
SortType string
@@ -887,10 +886,18 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
887886

888887
if opts.AssigneeID > 0 {
889888
sess.And("issue.assignee_id=?", opts.AssigneeID)
890-
} else if opts.PosterID > 0 {
889+
}
890+
891+
if opts.PosterID > 0 {
891892
sess.And("issue.poster_id=?", opts.PosterID)
892893
}
893894

895+
if opts.MentionedID > 0 {
896+
sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
897+
And("issue_user.is_mentioned = ?", true).
898+
And("issue_user.uid = ?", opts.MentionedID)
899+
}
900+
894901
if opts.MilestoneID > 0 {
895902
sess.And("issue.milestone_id=?", opts.MilestoneID)
896903
}
@@ -926,16 +933,6 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
926933
}
927934
}
928935

929-
if opts.IsMention {
930-
sess.
931-
Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
932-
And("issue_user.is_mentioned = ?", true)
933-
934-
if opts.UserID > 0 {
935-
sess.And("issue_user.uid = ?", opts.UserID)
936-
}
937-
}
938-
939936
issues := make([]*Issue, 0, setting.UI.IssuePagingNum)
940937
if err := sess.Find(&issues); err != nil {
941938
return nil, fmt.Errorf("Find: %v", err)
@@ -1156,11 +1153,11 @@ func parseCountResult(results []map[string][]byte) int64 {
11561153
// IssueStatsOptions contains parameters accepted by GetIssueStats.
11571154
type IssueStatsOptions struct {
11581155
RepoID int64
1159-
UserID int64
11601156
Labels string
11611157
MilestoneID int64
11621158
AssigneeID int64
1163-
FilterMode int
1159+
MentionedID int64
1160+
PosterID int64
11641161
IsPull bool
11651162
}
11661163

@@ -1191,43 +1188,25 @@ func GetIssueStats(opts *IssueStatsOptions) *IssueStats {
11911188
sess.And("assignee_id = ?", opts.AssigneeID)
11921189
}
11931190

1194-
return sess
1195-
}
1196-
1197-
switch opts.FilterMode {
1198-
case FilterModeAll, FilterModeAssign:
1199-
stats.OpenCount, _ = countSession(opts).
1200-
And("is_closed = ?", false).
1201-
Count(&Issue{})
1191+
if opts.PosterID > 0 {
1192+
sess.And("poster_id = ?", opts.PosterID)
1193+
}
12021194

1203-
stats.ClosedCount, _ = countSession(opts).
1204-
And("is_closed = ?", true).
1205-
Count(&Issue{})
1206-
case FilterModeCreate:
1207-
stats.OpenCount, _ = countSession(opts).
1208-
And("poster_id = ?", opts.UserID).
1209-
And("is_closed = ?", false).
1210-
Count(&Issue{})
1211-
1212-
stats.ClosedCount, _ = countSession(opts).
1213-
And("poster_id = ?", opts.UserID).
1214-
And("is_closed = ?", true).
1215-
Count(&Issue{})
1216-
case FilterModeMention:
1217-
stats.OpenCount, _ = countSession(opts).
1218-
Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
1219-
And("issue_user.uid = ?", opts.UserID).
1220-
And("issue_user.is_mentioned = ?", true).
1221-
And("issue.is_closed = ?", false).
1222-
Count(&Issue{})
1195+
if opts.MentionedID > 0 {
1196+
sess.Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
1197+
And("issue_user.uid = ?", opts.MentionedID).
1198+
And("issue_user.is_mentioned = ?", true)
1199+
}
12231200

1224-
stats.ClosedCount, _ = countSession(opts).
1225-
Join("INNER", "issue_user", "issue.id = issue_user.issue_id").
1226-
And("issue_user.uid = ?", opts.UserID).
1227-
And("issue_user.is_mentioned = ?", true).
1228-
And("issue.is_closed = ?", true).
1229-
Count(&Issue{})
1201+
return sess
12301202
}
1203+
1204+
stats.OpenCount, _ = countSession(opts).
1205+
And("is_closed = ?", false).
1206+
Count(&Issue{})
1207+
stats.ClosedCount, _ = countSession(opts).
1208+
And("is_closed = ?", true).
1209+
Count(&Issue{})
12311210
return stats
12321211
}
12331212

routers/repo/issue.go

+47-37
Original file line numberDiff line numberDiff line change
@@ -130,38 +130,42 @@ func Issues(ctx *context.Context) {
130130

131131
var (
132132
assigneeID = ctx.QueryInt64("assignee")
133-
posterID int64
133+
posterID int64
134+
mentionedID int64
135+
forceEmpty bool
134136
)
135-
filterMode := models.FilterModeAll
136137
switch viewType {
137138
case "assigned":
138-
filterMode = models.FilterModeAssign
139-
assigneeID = ctx.User.ID
139+
if assigneeID > 0 && ctx.User.ID != assigneeID {
140+
// two different assignees, must be empty
141+
forceEmpty = true
142+
} else {
143+
assigneeID = ctx.User.ID
144+
}
140145
case "created_by":
141-
filterMode = models.FilterModeCreate
142146
posterID = ctx.User.ID
143147
case "mentioned":
144-
filterMode = models.FilterModeMention
145-
}
146-
147-
var uid int64 = -1
148-
if ctx.IsSigned {
149-
uid = ctx.User.ID
148+
mentionedID = ctx.User.ID
150149
}
151150

152151
repo := ctx.Repo.Repository
153152
selectLabels := ctx.Query("labels")
154153
milestoneID := ctx.QueryInt64("milestone")
155154
isShowClosed := ctx.Query("state") == "closed"
156-
issueStats := models.GetIssueStats(&models.IssueStatsOptions{
157-
RepoID: repo.ID,
158-
UserID: uid,
159-
Labels: selectLabels,
160-
MilestoneID: milestoneID,
161-
AssigneeID: assigneeID,
162-
FilterMode: filterMode,
163-
IsPull: isPullList,
164-
})
155+
156+
var issueStats *models.IssueStats
157+
if forceEmpty {
158+
issueStats = &models.IssueStats{}
159+
} else {
160+
issueStats = models.GetIssueStats(&models.IssueStatsOptions{
161+
RepoID: repo.ID,
162+
Labels: selectLabels,
163+
MilestoneID: milestoneID,
164+
AssigneeID: assigneeID,
165+
MentionedID: mentionedID,
166+
IsPull: isPullList,
167+
})
168+
}
165169

166170
page := ctx.QueryInt("page")
167171
if page <= 1 {
@@ -177,22 +181,28 @@ func Issues(ctx *context.Context) {
177181
pager := paginater.New(total, setting.UI.IssuePagingNum, page, 5)
178182
ctx.Data["Page"] = pager
179183

180-
issues, err := models.Issues(&models.IssuesOptions{
181-
UserID: uid,
182-
AssigneeID: assigneeID,
183-
RepoID: repo.ID,
184-
PosterID: posterID,
185-
MilestoneID: milestoneID,
186-
Page: pager.Current(),
187-
IsClosed: isShowClosed,
188-
IsMention: filterMode == models.FilterModeMention,
189-
IsPull: isPullList,
190-
Labels: selectLabels,
191-
SortType: sortType,
192-
})
193-
if err != nil {
194-
ctx.Handle(500, "Issues", err)
195-
return
184+
185+
var issues []*models.Issue
186+
if forceEmpty {
187+
issues = []*models.Issue{}
188+
} else {
189+
var err error
190+
issues, err = models.Issues(&models.IssuesOptions{
191+
AssigneeID: assigneeID,
192+
RepoID: repo.ID,
193+
PosterID: posterID,
194+
MentionedID: mentionedID,
195+
MilestoneID: milestoneID,
196+
Page: pager.Current(),
197+
IsClosed: isShowClosed,
198+
IsPull: isPullList,
199+
Labels: selectLabels,
200+
SortType: sortType,
201+
})
202+
if err != nil {
203+
ctx.Handle(500, "Issues", err)
204+
return
205+
}
196206
}
197207

198208
// Get issue-user relations.
@@ -233,7 +243,7 @@ func Issues(ctx *context.Context) {
233243
return
234244
}
235245

236-
if viewType == "assigned" {
246+
if ctx.QueryInt64("assignee") == 0 {
237247
assigneeID = 0 // Reset ID to prevent unexpected selection of assignee.
238248
}
239249

routers/user/home.go

-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,6 @@ func Issues(ctx *context.Context) {
272272

273273
// Get issues.
274274
issues, err := models.Issues(&models.IssuesOptions{
275-
UserID: ctxUser.ID,
276275
AssigneeID: assigneeID,
277276
RepoID: repoID,
278277
PosterID: posterID,

0 commit comments

Comments
 (0)