aboutsummaryrefslogtreecommitdiffstats
path: root/routers/web
diff options
context:
space:
mode:
authorAndreas Svanberg <andreas.svanberg@mensa.se>2025-03-21 05:25:36 +0100
committerGitHub <noreply@github.com>2025-03-21 04:25:36 +0000
commit0da7318cf3b4933ec76ba7730daa1deacfcb0e78 (patch)
tree822c2d7f792fe376a4d40c950b50fb56eae8c4d1 /routers/web
parenta4df01b5802c62863cdf26dc747e20617d847d89 (diff)
downloadgitea-main.tar.gz
gitea-main.zip
Allow filtering issues by any assignee (#33343)HEADmain
This is the opposite of the "No assignee" filter, it will match all issues that have at least one assignee. Before ![Before change](https://github.com/user-attachments/assets/4aea194b-9add-4a84-8d6b-61bfd8d9e58e) After ![After change with any filter](https://github.com/user-attachments/assets/99f1205d-ba9f-4a0a-a60b-cc1a0c0823fe) --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'routers/web')
-rw-r--r--routers/web/org/projects.go4
-rw-r--r--routers/web/repo/issue_list.go18
-rw-r--r--routers/web/repo/projects.go4
-rw-r--r--routers/web/shared/user/helper.go19
-rw-r--r--routers/web/user/home.go16
5 files changed, 30 insertions, 31 deletions
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 985fd2ca45..49f4792772 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -347,11 +347,11 @@ func ViewProject(ctx *context.Context) {
if ctx.Written() {
return
}
- assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future
+ assigneeID := ctx.FormString("assignee")
opts := issues_model.IssuesOptions{
LabelIDs: labelIDs,
- AssigneeID: optional.Some(assigneeID),
+ AssigneeID: assigneeID,
Owner: project.Owner,
Doer: ctx.Doer,
}
diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go
index a65ae77795..69b38c81ec 100644
--- a/routers/web/repo/issue_list.go
+++ b/routers/web/repo/issue_list.go
@@ -208,10 +208,10 @@ func SearchIssues(ctx *context.Context) {
if ctx.IsSigned {
ctxUserID := ctx.Doer.ID
if ctx.FormBool("created") {
- searchOpt.PosterID = optional.Some(ctxUserID)
+ searchOpt.PosterID = strconv.FormatInt(ctxUserID, 10)
}
if ctx.FormBool("assigned") {
- searchOpt.AssigneeID = optional.Some(ctxUserID)
+ searchOpt.AssigneeID = strconv.FormatInt(ctxUserID, 10)
}
if ctx.FormBool("mentioned") {
searchOpt.MentionID = optional.Some(ctxUserID)
@@ -373,10 +373,10 @@ func SearchRepoIssuesJSON(ctx *context.Context) {
}
if createdByID > 0 {
- searchOpt.PosterID = optional.Some(createdByID)
+ searchOpt.PosterID = strconv.FormatInt(createdByID, 10)
}
if assignedByID > 0 {
- searchOpt.AssigneeID = optional.Some(assignedByID)
+ searchOpt.AssigneeID = strconv.FormatInt(assignedByID, 10)
}
if mentionedByID > 0 {
searchOpt.MentionID = optional.Some(mentionedByID)
@@ -490,7 +490,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
viewType = "all"
}
- assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future
+ assigneeID := ctx.FormString("assignee")
posterUsername := ctx.FormString("poster")
posterUserID := shared_user.GetFilterUserIDByName(ctx, posterUsername)
var mentionedID, reviewRequestedID, reviewedID int64
@@ -498,11 +498,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
if ctx.IsSigned {
switch viewType {
case "created_by":
- posterUserID = optional.Some(ctx.Doer.ID)
+ posterUserID = strconv.FormatInt(ctx.Doer.ID, 10)
case "mentioned":
mentionedID = ctx.Doer.ID
case "assigned":
- assigneeID = ctx.Doer.ID
+ assigneeID = fmt.Sprint(ctx.Doer.ID)
case "review_requested":
reviewRequestedID = ctx.Doer.ID
case "reviewed_by":
@@ -532,7 +532,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
LabelIDs: labelIDs,
MilestoneIDs: mileIDs,
ProjectID: projectID,
- AssigneeID: optional.Some(assigneeID),
+ AssigneeID: assigneeID,
MentionedID: mentionedID,
PosterID: posterUserID,
ReviewRequestedID: reviewRequestedID,
@@ -613,7 +613,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
PageSize: setting.UI.IssuePagingNum,
},
RepoIDs: []int64{repo.ID},
- AssigneeID: optional.Some(assigneeID),
+ AssigneeID: assigneeID,
PosterID: posterUserID,
MentionedID: mentionedID,
ReviewRequestedID: reviewRequestedID,
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index 5b81a5e4d1..6810025c6f 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -315,12 +315,12 @@ func ViewProject(ctx *context.Context) {
labelIDs := issue.PrepareFilterIssueLabels(ctx, ctx.Repo.Repository.ID, ctx.Repo.Owner)
- assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future
+ assigneeID := ctx.FormString("assignee")
issuesMap, err := project_service.LoadIssuesFromProject(ctx, project, &issues_model.IssuesOptions{
RepoIDs: []int64{ctx.Repo.Repository.ID},
LabelIDs: labelIDs,
- AssigneeID: optional.Some(assigneeID),
+ AssigneeID: assigneeID,
})
if err != nil {
ctx.ServerError("LoadIssuesOfColumns", err)
diff --git a/routers/web/shared/user/helper.go b/routers/web/shared/user/helper.go
index b82181a1df..3fc39fd3ab 100644
--- a/routers/web/shared/user/helper.go
+++ b/routers/web/shared/user/helper.go
@@ -8,9 +8,7 @@ import (
"slices"
"strconv"
- "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
)
func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User {
@@ -34,19 +32,20 @@ func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User {
// So it's better to make it work like GitHub: users could input username directly.
// Since it only converts the username to ID directly and is only used internally (to search issues), so no permission check is needed.
// Return values:
-// * nil: no filter
-// * some(id): match the id, the id could be -1 to match the issues without assignee
-// * some(NonExistingID): match no issue (due to the user doesn't exist)
-func GetFilterUserIDByName(ctx context.Context, name string) optional.Option[int64] {
+// * "": no filter
+// * "{the-id}": match the id
+// * "(none)": match no issue (due to the user doesn't exist)
+func GetFilterUserIDByName(ctx context.Context, name string) string {
if name == "" {
- return optional.None[int64]()
+ return ""
}
u, err := user.GetUserByName(ctx, name)
if err != nil {
if id, err := strconv.ParseInt(name, 10, 64); err == nil {
- return optional.Some(id)
+ return strconv.FormatInt(id, 10)
}
- return optional.Some(db.NonExistingID)
+ // The "(none)" is for internal usage only: when doer tries to search non-existing user, use "(none)" to return empty result.
+ return "(none)"
}
- return optional.Some(u.ID)
+ return strconv.FormatInt(u.ID, 10)
}
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 3973aea742..864a2831d1 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -501,9 +501,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
case issues_model.FilterModeAll:
case issues_model.FilterModeYourRepositories:
case issues_model.FilterModeAssign:
- opts.AssigneeID = optional.Some(ctx.Doer.ID)
+ opts.AssigneeID = strconv.FormatInt(ctx.Doer.ID, 10)
case issues_model.FilterModeCreate:
- opts.PosterID = optional.Some(ctx.Doer.ID)
+ opts.PosterID = strconv.FormatInt(ctx.Doer.ID, 10)
case issues_model.FilterModeMention:
opts.MentionedID = ctx.Doer.ID
case issues_model.FilterModeReviewRequested:
@@ -792,9 +792,9 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod
case issues_model.FilterModeYourRepositories:
openClosedOpts.AllPublic = false
case issues_model.FilterModeAssign:
- openClosedOpts.AssigneeID = optional.Some(doerID)
+ openClosedOpts.AssigneeID = strconv.FormatInt(doerID, 10)
case issues_model.FilterModeCreate:
- openClosedOpts.PosterID = optional.Some(doerID)
+ openClosedOpts.PosterID = strconv.FormatInt(doerID, 10)
case issues_model.FilterModeMention:
openClosedOpts.MentionID = optional.Some(doerID)
case issues_model.FilterModeReviewRequested:
@@ -816,8 +816,8 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod
// Below stats are for the left sidebar
opts = opts.Copy(func(o *issue_indexer.SearchOptions) {
- o.AssigneeID = nil
- o.PosterID = nil
+ o.AssigneeID = ""
+ o.PosterID = ""
o.MentionID = nil
o.ReviewRequestedID = nil
o.ReviewedID = nil
@@ -827,11 +827,11 @@ func getUserIssueStats(ctx *context.Context, ctxUser *user_model.User, filterMod
if err != nil {
return nil, err
}
- ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = optional.Some(doerID) }))
+ ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = strconv.FormatInt(doerID, 10) }))
if err != nil {
return nil, err
}
- ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = optional.Some(doerID) }))
+ ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = strconv.FormatInt(doerID, 10) }))
if err != nil {
return nil, err
}