Skip to content

Commit b94f49e

Browse files
lunnyStelios Malathouras
authored and
Stelios Malathouras
committed
Support pagination of organizations on user settings pages (go-gitea#16083)
* Add pagination for user setting orgs * Use FindOrgs instead of GetOrgsByUserID * Remove unnecessary functions and fix test * remove unnecessary code
1 parent 03c514c commit b94f49e

File tree

7 files changed

+108
-34
lines changed

7 files changed

+108
-34
lines changed

integrations/org_count_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ func doCheckOrgCounts(username string, orgCounts map[string]int, strict bool, ca
116116
Name: username,
117117
}).(*models.User)
118118

119-
orgs, err := models.GetOrgsByUserID(user.ID, true)
119+
orgs, err := models.FindOrgs(models.FindOrgOptions{
120+
UserID: user.ID,
121+
IncludePrivate: true,
122+
})
120123
assert.NoError(t, err)
121124

122125
calcOrgCounts := map[string]int{}

models/org.go

+45-18
Original file line numberDiff line numberDiff line change
@@ -440,24 +440,6 @@ func getUsersWhoCanCreateOrgRepo(e db.Engine, orgID int64) ([]*User, error) {
440440
And("team_user.org_id = ?", orgID).Asc("`user`.name").Find(&users)
441441
}
442442

443-
func getOrgsByUserID(e db.Engine, userID int64, showAll bool) ([]*Organization, error) {
444-
orgs := make([]*Organization, 0, 10)
445-
sess := e.Where("`org_user`.uid=?", userID)
446-
if !showAll {
447-
sess = sess.And("`org_user`.is_public=?", true)
448-
}
449-
return orgs, sess.
450-
Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").
451-
Asc("`user`.name").
452-
Find(&orgs)
453-
}
454-
455-
// GetOrgsByUserID returns a list of organizations that the given user ID
456-
// has joined.
457-
func GetOrgsByUserID(userID int64, showAll bool) ([]*Organization, error) {
458-
return getOrgsByUserID(db.GetEngine(db.DefaultContext), userID, showAll)
459-
}
460-
461443
// MinimalOrg represents a simple orgnization with only needed columns
462444
type MinimalOrg = Organization
463445

@@ -519,6 +501,51 @@ func GetUserOrgsList(user *User) ([]*MinimalOrg, error) {
519501
return orgs, nil
520502
}
521503

504+
// FindOrgOptions finds orgs options
505+
type FindOrgOptions struct {
506+
db.ListOptions
507+
UserID int64
508+
IncludePrivate bool
509+
}
510+
511+
func queryUserOrgIDs(userID int64, includePrivate bool) *builder.Builder {
512+
var cond = builder.Eq{"uid": userID}
513+
if !includePrivate {
514+
cond["is_public"] = true
515+
}
516+
return builder.Select("org_id").From("org_user").Where(cond)
517+
}
518+
519+
func (opts FindOrgOptions) toConds() builder.Cond {
520+
var cond = builder.NewCond()
521+
if opts.UserID > 0 {
522+
cond = cond.And(builder.In("`user`.`id`", queryUserOrgIDs(opts.UserID, opts.IncludePrivate)))
523+
}
524+
if !opts.IncludePrivate {
525+
cond = cond.And(builder.Eq{"`user`.visibility": structs.VisibleTypePublic})
526+
}
527+
return cond
528+
}
529+
530+
// FindOrgs returns a list of organizations according given conditions
531+
func FindOrgs(opts FindOrgOptions) ([]*Organization, error) {
532+
orgs := make([]*Organization, 0, 10)
533+
sess := db.GetEngine(db.DefaultContext).
534+
Where(opts.toConds()).
535+
Asc("`user`.name")
536+
if opts.Page > 0 && opts.PageSize > 0 {
537+
sess.Limit(opts.PageSize, opts.PageSize*(opts.Page-1))
538+
}
539+
return orgs, sess.Find(&orgs)
540+
}
541+
542+
// CountOrgs returns total count organizations according options
543+
func CountOrgs(opts FindOrgOptions) (int64, error) {
544+
return db.GetEngine(db.DefaultContext).
545+
Where(opts.toConds()).
546+
Count(new(User))
547+
}
548+
522549
func getOwnedOrgsByUserID(sess db.Engine, userID int64) ([]*User, error) {
523550
orgs := make([]*User, 0, 10)
524551
return orgs, sess.

models/org_test.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -307,18 +307,31 @@ func TestIsPublicMembership(t *testing.T) {
307307
test(unittest.NonexistentID, unittest.NonexistentID, false)
308308
}
309309

310-
func TestGetOrgsByUserID(t *testing.T) {
310+
func TestFindOrgs(t *testing.T) {
311311
assert.NoError(t, unittest.PrepareTestDatabase())
312312

313-
orgs, err := GetOrgsByUserID(4, true)
313+
orgs, err := FindOrgs(FindOrgOptions{
314+
UserID: 4,
315+
IncludePrivate: true,
316+
})
314317
assert.NoError(t, err)
315318
if assert.Len(t, orgs, 1) {
316319
assert.EqualValues(t, 3, orgs[0].ID)
317320
}
318321

319-
orgs, err = GetOrgsByUserID(4, false)
322+
orgs, err = FindOrgs(FindOrgOptions{
323+
UserID: 4,
324+
IncludePrivate: false,
325+
})
320326
assert.NoError(t, err)
321327
assert.Len(t, orgs, 0)
328+
329+
total, err := CountOrgs(FindOrgOptions{
330+
UserID: 4,
331+
IncludePrivate: true,
332+
})
333+
assert.NoError(t, err)
334+
assert.EqualValues(t, 1, total)
322335
}
323336

324337
func TestGetOwnedOrgsByUserID(t *testing.T) {

routers/api/v1/org/org.go

+13-8
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,38 @@ import (
1212
"code.gitea.io/gitea/modules/context"
1313
"code.gitea.io/gitea/modules/convert"
1414
api "code.gitea.io/gitea/modules/structs"
15-
"code.gitea.io/gitea/modules/util"
1615
"code.gitea.io/gitea/modules/web"
1716
"code.gitea.io/gitea/routers/api/v1/user"
1817
"code.gitea.io/gitea/routers/api/v1/utils"
1918
"code.gitea.io/gitea/services/org"
2019
)
2120

2221
func listUserOrgs(ctx *context.APIContext, u *models.User) {
23-
2422
listOptions := utils.GetListOptions(ctx)
2523
showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == u.ID)
2624

27-
orgs, err := models.GetOrgsByUserID(u.ID, showPrivate)
25+
var opts = models.FindOrgOptions{
26+
ListOptions: listOptions,
27+
UserID: u.ID,
28+
IncludePrivate: showPrivate,
29+
}
30+
orgs, err := models.FindOrgs(opts)
2831
if err != nil {
29-
ctx.Error(http.StatusInternalServerError, "GetOrgsByUserID", err)
32+
ctx.Error(http.StatusInternalServerError, "FindOrgs", err)
33+
return
34+
}
35+
maxResults, err := models.CountOrgs(opts)
36+
if err != nil {
37+
ctx.Error(http.StatusInternalServerError, "CountOrgs", err)
3038
return
3139
}
32-
33-
maxResults := len(orgs)
34-
orgs, _ = util.PaginateSlice(orgs, listOptions.Page, listOptions.PageSize).([]*models.Organization)
3540

3641
apiOrgs := make([]*api.Organization, len(orgs))
3742
for i := range orgs {
3843
apiOrgs[i] = convert.ToOrganization(orgs[i])
3944
}
4045

41-
ctx.SetLinkHeader(maxResults, listOptions.PageSize)
46+
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
4247
ctx.SetTotalCountHeader(int64(maxResults))
4348
ctx.JSON(http.StatusOK, &apiOrgs)
4449
}

routers/web/user/profile.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,12 @@ func Profile(ctx *context.Context) {
167167

168168
showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID)
169169

170-
orgs, err := models.GetOrgsByUserID(ctxUser.ID, showPrivate)
170+
orgs, err := models.FindOrgs(models.FindOrgOptions{
171+
UserID: ctxUser.ID,
172+
IncludePrivate: showPrivate,
173+
})
171174
if err != nil {
172-
ctx.ServerError("GetOrgsByUserIDDesc", err)
175+
ctx.ServerError("FindOrgs", err)
173176
return
174177
}
175178

routers/web/user/setting/profile.go

+24-2
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,34 @@ func DeleteAvatar(ctx *context.Context) {
214214
func Organization(ctx *context.Context) {
215215
ctx.Data["Title"] = ctx.Tr("settings")
216216
ctx.Data["PageIsSettingsOrganization"] = true
217-
orgs, err := models.GetOrgsByUserID(ctx.User.ID, ctx.IsSigned)
217+
218+
opts := models.FindOrgOptions{
219+
ListOptions: db.ListOptions{
220+
PageSize: setting.UI.Admin.UserPagingNum,
221+
Page: ctx.FormInt("page"),
222+
},
223+
UserID: ctx.User.ID,
224+
IncludePrivate: ctx.IsSigned,
225+
}
226+
227+
if opts.Page <= 0 {
228+
opts.Page = 1
229+
}
230+
231+
orgs, err := models.FindOrgs(opts)
232+
if err != nil {
233+
ctx.ServerError("FindOrgs", err)
234+
return
235+
}
236+
total, err := models.CountOrgs(opts)
218237
if err != nil {
219-
ctx.ServerError("GetOrgsByUserID", err)
238+
ctx.ServerError("CountOrgs", err)
220239
return
221240
}
222241
ctx.Data["Orgs"] = orgs
242+
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
243+
pager.SetDefaultParams(ctx)
244+
ctx.Data["Page"] = pager
223245
ctx.HTML(http.StatusOK, tplSettingsOrganization)
224246
}
225247

templates/user/settings/organization.tmpl

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
</div>
3030
{{end}}
3131
</div>
32+
{{template "base/paginate" .}}
3233
{{else}}
3334
{{.i18n.Tr "settings.orgs_none"}}
3435
{{end}}

0 commit comments

Comments
 (0)