summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-11-22 21:51:45 +0800
committerGitHub <noreply@github.com>2021-11-22 21:51:45 +0800
commitc2ab19888f92fbdec4276a16d224e8de80d1d1dd (patch)
tree1fdbf05d1b6d2a99e88e8219133a252fce6562d5
parented23a6c39704c329ec4940bfec16739a0d3d3e91 (diff)
downloadgitea-c2ab19888f92fbdec4276a16d224e8de80d1d1dd.tar.gz
gitea-c2ab19888f92fbdec4276a16d224e8de80d1d1dd.zip
Support pagination of organizations on user settings pages (#16083)
* Add pagination for user setting orgs * Use FindOrgs instead of GetOrgsByUserID * Remove unnecessary functions and fix test * remove unnecessary code
-rw-r--r--integrations/org_count_test.go5
-rw-r--r--models/org.go63
-rw-r--r--models/org_test.go19
-rw-r--r--routers/api/v1/org/org.go21
-rw-r--r--routers/web/user/profile.go7
-rw-r--r--routers/web/user/setting/profile.go26
-rw-r--r--templates/user/settings/organization.tmpl1
7 files changed, 108 insertions, 34 deletions
diff --git a/integrations/org_count_test.go b/integrations/org_count_test.go
index a394dba01c..a45d1e81b5 100644
--- a/integrations/org_count_test.go
+++ b/integrations/org_count_test.go
@@ -116,7 +116,10 @@ func doCheckOrgCounts(username string, orgCounts map[string]int, strict bool, ca
Name: username,
}).(*models.User)
- orgs, err := models.GetOrgsByUserID(user.ID, true)
+ orgs, err := models.FindOrgs(models.FindOrgOptions{
+ UserID: user.ID,
+ IncludePrivate: true,
+ })
assert.NoError(t, err)
calcOrgCounts := map[string]int{}
diff --git a/models/org.go b/models/org.go
index 8e60422ef1..b3e67fb521 100644
--- a/models/org.go
+++ b/models/org.go
@@ -440,24 +440,6 @@ func getUsersWhoCanCreateOrgRepo(e db.Engine, orgID int64) ([]*User, error) {
And("team_user.org_id = ?", orgID).Asc("`user`.name").Find(&users)
}
-func getOrgsByUserID(e db.Engine, userID int64, showAll bool) ([]*Organization, error) {
- orgs := make([]*Organization, 0, 10)
- sess := e.Where("`org_user`.uid=?", userID)
- if !showAll {
- sess = sess.And("`org_user`.is_public=?", true)
- }
- return orgs, sess.
- Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").
- Asc("`user`.name").
- Find(&orgs)
-}
-
-// GetOrgsByUserID returns a list of organizations that the given user ID
-// has joined.
-func GetOrgsByUserID(userID int64, showAll bool) ([]*Organization, error) {
- return getOrgsByUserID(db.GetEngine(db.DefaultContext), userID, showAll)
-}
-
// MinimalOrg represents a simple orgnization with only needed columns
type MinimalOrg = Organization
@@ -519,6 +501,51 @@ func GetUserOrgsList(user *User) ([]*MinimalOrg, error) {
return orgs, nil
}
+// FindOrgOptions finds orgs options
+type FindOrgOptions struct {
+ db.ListOptions
+ UserID int64
+ IncludePrivate bool
+}
+
+func queryUserOrgIDs(userID int64, includePrivate bool) *builder.Builder {
+ var cond = builder.Eq{"uid": userID}
+ if !includePrivate {
+ cond["is_public"] = true
+ }
+ return builder.Select("org_id").From("org_user").Where(cond)
+}
+
+func (opts FindOrgOptions) toConds() builder.Cond {
+ var cond = builder.NewCond()
+ if opts.UserID > 0 {
+ cond = cond.And(builder.In("`user`.`id`", queryUserOrgIDs(opts.UserID, opts.IncludePrivate)))
+ }
+ if !opts.IncludePrivate {
+ cond = cond.And(builder.Eq{"`user`.visibility": structs.VisibleTypePublic})
+ }
+ return cond
+}
+
+// FindOrgs returns a list of organizations according given conditions
+func FindOrgs(opts FindOrgOptions) ([]*Organization, error) {
+ orgs := make([]*Organization, 0, 10)
+ sess := db.GetEngine(db.DefaultContext).
+ Where(opts.toConds()).
+ Asc("`user`.name")
+ if opts.Page > 0 && opts.PageSize > 0 {
+ sess.Limit(opts.PageSize, opts.PageSize*(opts.Page-1))
+ }
+ return orgs, sess.Find(&orgs)
+}
+
+// CountOrgs returns total count organizations according options
+func CountOrgs(opts FindOrgOptions) (int64, error) {
+ return db.GetEngine(db.DefaultContext).
+ Where(opts.toConds()).
+ Count(new(User))
+}
+
func getOwnedOrgsByUserID(sess db.Engine, userID int64) ([]*User, error) {
orgs := make([]*User, 0, 10)
return orgs, sess.
diff --git a/models/org_test.go b/models/org_test.go
index 10ae877458..805c63300b 100644
--- a/models/org_test.go
+++ b/models/org_test.go
@@ -307,18 +307,31 @@ func TestIsPublicMembership(t *testing.T) {
test(unittest.NonexistentID, unittest.NonexistentID, false)
}
-func TestGetOrgsByUserID(t *testing.T) {
+func TestFindOrgs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- orgs, err := GetOrgsByUserID(4, true)
+ orgs, err := FindOrgs(FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: true,
+ })
assert.NoError(t, err)
if assert.Len(t, orgs, 1) {
assert.EqualValues(t, 3, orgs[0].ID)
}
- orgs, err = GetOrgsByUserID(4, false)
+ orgs, err = FindOrgs(FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: false,
+ })
assert.NoError(t, err)
assert.Len(t, orgs, 0)
+
+ total, err := CountOrgs(FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: true,
+ })
+ assert.NoError(t, err)
+ assert.EqualValues(t, 1, total)
}
func TestGetOwnedOrgsByUserID(t *testing.T) {
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
index bbf127f891..f539662d62 100644
--- a/routers/api/v1/org/org.go
+++ b/routers/api/v1/org/org.go
@@ -12,7 +12,6 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/routers/api/v1/utils"
@@ -20,25 +19,31 @@ import (
)
func listUserOrgs(ctx *context.APIContext, u *models.User) {
-
listOptions := utils.GetListOptions(ctx)
showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == u.ID)
- orgs, err := models.GetOrgsByUserID(u.ID, showPrivate)
+ var opts = models.FindOrgOptions{
+ ListOptions: listOptions,
+ UserID: u.ID,
+ IncludePrivate: showPrivate,
+ }
+ orgs, err := models.FindOrgs(opts)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetOrgsByUserID", err)
+ ctx.Error(http.StatusInternalServerError, "FindOrgs", err)
+ return
+ }
+ maxResults, err := models.CountOrgs(opts)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "CountOrgs", err)
return
}
-
- maxResults := len(orgs)
- orgs, _ = util.PaginateSlice(orgs, listOptions.Page, listOptions.PageSize).([]*models.Organization)
apiOrgs := make([]*api.Organization, len(orgs))
for i := range orgs {
apiOrgs[i] = convert.ToOrganization(orgs[i])
}
- ctx.SetLinkHeader(maxResults, listOptions.PageSize)
+ ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
ctx.SetTotalCountHeader(int64(maxResults))
ctx.JSON(http.StatusOK, &apiOrgs)
}
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 72d36761da..9d0b4e3c15 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -167,9 +167,12 @@ func Profile(ctx *context.Context) {
showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
- orgs, err := models.GetOrgsByUserID(ctxUser.ID, showPrivate)
+ orgs, err := models.FindOrgs(models.FindOrgOptions{
+ UserID: ctxUser.ID,
+ IncludePrivate: showPrivate,
+ })
if err != nil {
- ctx.ServerError("GetOrgsByUserIDDesc", err)
+ ctx.ServerError("FindOrgs", err)
return
}
diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go
index d7aa3264c5..36fe45df04 100644
--- a/routers/web/user/setting/profile.go
+++ b/routers/web/user/setting/profile.go
@@ -214,12 +214,34 @@ func DeleteAvatar(ctx *context.Context) {
func Organization(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsSettingsOrganization"] = true
- orgs, err := models.GetOrgsByUserID(ctx.User.ID, ctx.IsSigned)
+
+ opts := models.FindOrgOptions{
+ ListOptions: db.ListOptions{
+ PageSize: setting.UI.Admin.UserPagingNum,
+ Page: ctx.FormInt("page"),
+ },
+ UserID: ctx.User.ID,
+ IncludePrivate: ctx.IsSigned,
+ }
+
+ if opts.Page <= 0 {
+ opts.Page = 1
+ }
+
+ orgs, err := models.FindOrgs(opts)
+ if err != nil {
+ ctx.ServerError("FindOrgs", err)
+ return
+ }
+ total, err := models.CountOrgs(opts)
if err != nil {
- ctx.ServerError("GetOrgsByUserID", err)
+ ctx.ServerError("CountOrgs", err)
return
}
ctx.Data["Orgs"] = orgs
+ pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
+ pager.SetDefaultParams(ctx)
+ ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplSettingsOrganization)
}
diff --git a/templates/user/settings/organization.tmpl b/templates/user/settings/organization.tmpl
index 3bab1c8957..1689c1b9e2 100644
--- a/templates/user/settings/organization.tmpl
+++ b/templates/user/settings/organization.tmpl
@@ -29,6 +29,7 @@
</div>
{{end}}
</div>
+ {{template "base/paginate" .}}
{{else}}
{{.i18n.Tr "settings.orgs_none"}}
{{end}}