diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go index dd2ef6220116b..c823bdceb5f0e 100644 --- a/models/repo/user_repo.go +++ b/models/repo/user_repo.go @@ -177,3 +177,22 @@ func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull boo Limit(30). Find(&users) } + +// GetIssuePostersWithSearchWithoutRepo clone of GetIssuePostersWithSearch without repo +func GetIssuePostersWithSearchWithoutRepo(ctx context.Context, search string, isShowFullName bool) ([]*user_model.User, error) { + users := make([]*user_model.User, 0, 30) + var prefixCond builder.Cond = builder.Like{"name", search + "%"} + if isShowFullName { + prefixCond = prefixCond.Or(builder.Like{"full_name", "%" + search + "%"}) + } + + cond := builder.In("`user`.id", + builder.Select("poster_id").From("issue").GroupBy("poster_id")).And(prefixCond) + + return users, db.GetEngine(ctx). + Where(cond). + Cols("id", "name", "full_name", "avatar", "avatar_email", "use_custom_avatar"). + OrderBy("name"). + Limit(30). + Find(&users) +} diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index b04802e4520df..a23a6cbb13e78 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -3581,6 +3581,11 @@ func IssuePosters(ctx *context.Context) { issuePosters(ctx, false) } +// IssuePostersWithoutRepo clone of IssuePosters but without repo +func IssuePostersWithoutRepo(ctx *context.Context) { + issuePostersWithoutRepo(ctx) +} + func PullPosters(ctx *context.Context) { issuePosters(ctx, true) } @@ -3614,3 +3619,32 @@ func issuePosters(ctx *context.Context, isPullList bool) { } ctx.JSON(http.StatusOK, resp) } + +func issuePostersWithoutRepo(ctx *context.Context) { + search := strings.TrimSpace(ctx.FormString("q")) + posters, err := repo_model.GetIssuePostersWithSearchWithoutRepo(ctx, search, setting.UI.DefaultShowFullName) + if err != nil { + ctx.JSON(http.StatusInternalServerError, err) + return + } + + if search == "" && ctx.Doer != nil { + // the returned posters slice only contains limited number of users, + // to make the current user (doer) can quickly filter their own issues, always add doer to the posters slice + if !util.SliceContainsFunc(posters, func(user *user_model.User) bool { return user.ID == ctx.Doer.ID }) { + posters = append(posters, ctx.Doer) + } + } + + posters = MakeSelfOnTop(ctx, posters) + + resp := &userSearchResponse{} + resp.Results = make([]*userSearchInfo, len(posters)) + for i, user := range posters { + resp.Results[i] = &userSearchInfo{UserID: user.ID, UserName: user.Name, AvatarLink: user.AvatarLink(ctx)} + if setting.UI.DefaultShowFullName { + resp.Results[i].FullName = user.FullName + } + } + ctx.JSON(http.StatusOK, resp) +} diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 8c1447f707863..a944bc39a8ff1 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -485,6 +485,18 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { opts.ReviewedID = ctx.Doer.ID } + // Get filter by author id + filterByAuthorID, errorParsingAuthorID := strconv.ParseInt(ctx.FormString("author"), 10, 64) + if errorParsingAuthorID == nil { + opts.PosterID = filterByAuthorID + } + + // Get filter by assignee id + filterByAssigneeID, errorParsingAssigneeID := strconv.ParseInt(ctx.FormString("assignee"), 10, 64) + if errorParsingAssigneeID == nil { + opts.AssigneeID = filterByAssigneeID + } + // keyword holds the search term entered into the search field. keyword := strings.Trim(ctx.FormString("q"), " ") ctx.Data["Keyword"] = keyword @@ -746,6 +758,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { pager.AddParam(ctx, "labels", "SelectLabels") pager.AddParam(ctx, "milestone", "MilestoneID") pager.AddParam(ctx, "assignee", "AssigneeID") + pager.AddParam(ctx, "author", "AuthorID") ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplIssues) diff --git a/routers/web/web.go b/routers/web/web.go index e70e360d5991d..a495807d88a34 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -368,6 +368,8 @@ func registerRoutes(m *web.Route) { }, ignExploreSignIn) m.Group("/issues", func() { m.Get("", user.Issues) + m.Get("/posters", repo.IssuePostersWithoutRepo) + m.Get("/filter", user.Issues) m.Get("/search", repo.SearchIssues) }, reqSignIn) diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl index 8d6cc67afe17e..42c58a524afb0 100644 --- a/templates/user/dashboard/issues.tmpl +++ b/templates/user/dashboard/issues.tmpl @@ -1,7 +1,8 @@ {{template "base/head" .}}