From 4daf40505a5f89747982ddd2f1df2a4001720846 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Sat, 6 May 2023 10:04:55 -0400 Subject: [PATCH] Sort users and orgs on explore by recency by default (#24279) This gives more "freshness" to the explore page. So it's not just the same X users on the explore page by default, now it matches the same sort as the repos on the explore page. --------- Co-authored-by: Lunny Xiao --- modules/context/form.go | 5 +++++ routers/web/admin/orgs.go | 4 ++++ routers/web/admin/users.go | 3 ++- routers/web/explore/org.go | 4 ++++ routers/web/explore/user.go | 22 ++++++++++++++++------ tests/integration/setting_test.go | 4 ++-- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/modules/context/form.go b/modules/context/form.go index f9c4ab6a98..5c02152582 100644 --- a/modules/context/form.go +++ b/modules/context/form.go @@ -65,3 +65,8 @@ func (ctx *Context) FormOptionalBool(key string) util.OptionalBool { v = v || strings.EqualFold(s, "on") return util.OptionalBoolOf(v) } + +func (ctx *Context) SetFormString(key, value string) { + _ = ctx.Req.FormValue(key) // force parse form + ctx.Req.Form.Set(key, value) +} diff --git a/routers/web/admin/orgs.go b/routers/web/admin/orgs.go index 6a3617d67f..d0fd0d5002 100644 --- a/routers/web/admin/orgs.go +++ b/routers/web/admin/orgs.go @@ -23,6 +23,10 @@ func Organizations(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.organizations") ctx.Data["PageIsAdminOrganizations"] = true + if ctx.FormString("sort") == "" { + ctx.SetFormString("sort", explore.UserSearchDefaultAdminSort) + } + explore.RenderUserSearch(ctx, &user_model.SearchUserOptions{ Actor: ctx.Doer, Type: user_model.UserTypeOrganization, diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index 2150bc42f7..bd31d9d632 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -53,7 +53,8 @@ func Users(ctx *context.Context) { sortType := ctx.FormString("sort") if sortType == "" { - sortType = explore.UserSearchDefaultSortType + sortType = explore.UserSearchDefaultAdminSort + ctx.SetFormString("sort", sortType) } ctx.PageData["adminUserListSearchForm"] = map[string]interface{}{ "StatusFilterMap": statusFilterMap, diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go index c9fb05ff3a..c8b26c35ef 100644 --- a/routers/web/explore/org.go +++ b/routers/web/explore/org.go @@ -30,6 +30,10 @@ func Organizations(ctx *context.Context) { visibleTypes = append(visibleTypes, structs.VisibleTypeLimited, structs.VisibleTypePrivate) } + if ctx.FormString("sort") == "" { + ctx.SetFormString("sort", UserSearchDefaultSortType) + } + RenderUserSearch(ctx, &user_model.SearchUserOptions{ Actor: ctx.Doer, Type: user_model.UserTypeOrganization, diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index e00493c87b..a2b5f80099 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -24,7 +24,10 @@ const ( ) // UserSearchDefaultSortType is the default sort type for user search -const UserSearchDefaultSortType = "alphabetically" +const ( + UserSearchDefaultSortType = "recentupdate" + UserSearchDefaultAdminSort = "alphabetically" +) var nullByte = []byte{0x00} @@ -56,14 +59,13 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, ) // we can not set orderBy to `models.SearchOrderByXxx`, because there may be a JOIN in the statement, different tables may have the same name columns + ctx.Data["SortType"] = ctx.FormString("sort") switch ctx.FormString("sort") { case "newest": orderBy = "`user`.id DESC" case "oldest": orderBy = "`user`.id ASC" - case "recentupdate": - orderBy = "`user`.updated_unix DESC" case "leastupdate": orderBy = "`user`.updated_unix ASC" case "reversealphabetically": @@ -72,10 +74,14 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, orderBy = "`user`.last_login_unix ASC" case "reverselastlogin": orderBy = "`user`.last_login_unix DESC" - case UserSearchDefaultSortType: // "alphabetically" - default: + case "alphabetically": orderBy = "`user`.name ASC" - ctx.Data["SortType"] = UserSearchDefaultSortType + case "recentupdate": + fallthrough + default: + // in case the sortType is not valid, we set it to recentupdate + ctx.Data["SortType"] = "recentupdate" + orderBy = "`user`.updated_unix DESC" } opts.Keyword = ctx.FormTrim("q") @@ -127,6 +133,10 @@ func Users(ctx *context.Context) { ctx.Data["PageIsExploreUsers"] = true ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled + if ctx.FormString("sort") == "" { + ctx.SetFormString("sort", UserSearchDefaultSortType) + } + RenderUserSearch(ctx, &user_model.SearchUserOptions{ Actor: ctx.Doer, Type: user_model.UserTypeIndividual, diff --git a/tests/integration/setting_test.go b/tests/integration/setting_test.go index cb8248e6e2..a824bd7f2f 100644 --- a/tests/integration/setting_test.go +++ b/tests/integration/setting_test.go @@ -20,7 +20,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) { setting.UI.ShowUserEmail = true session := loginUser(t, "user2") - req := NewRequest(t, "GET", "/explore/users") + req := NewRequest(t, "GET", "/explore/users?sort=alphabetically") resp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) assert.Contains(t, @@ -30,7 +30,7 @@ func TestSettingShowUserEmailExplore(t *testing.T) { setting.UI.ShowUserEmail = false - req = NewRequest(t, "GET", "/explore/users") + req = NewRequest(t, "GET", "/explore/users?sort=alphabetically") resp = session.MakeRequest(t, req, http.StatusOK) htmlDoc = NewHTMLParser(t, resp.Body) assert.NotContains(t,