fix: paginate list of repositories in a team (#12549)

Follow-up to #12103 / !12447, which added pagination for lists of team members. @mahlzahn has [noticed](https://codeberg.org/forgejo/forgejo/issues/12103#issuecomment-14454947) that the same problem applies to the list of repositories controlled by a team, so this PR adds pagination for that too.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12549
Reviewed-by: Robert Wolff <mahlzahn@posteo.de>
This commit is contained in:
Antonin Delpeuch 2026-05-14 22:30:56 +02:00 committed by Gusted
parent 160377405c
commit 7eebf5642c
4 changed files with 44 additions and 3 deletions

View file

@ -150,13 +150,19 @@ func (t *Team) IsMember(ctx context.Context, userID int64) bool {
return isMember
}
// LoadRepositories returns paginated repositories in team of organization.
// LoadRepositories returns the repositories of the team in t.Repos.
func (t *Team) LoadRepositories(ctx context.Context) (err error) {
return t.LoadPaginatedRepositories(ctx, db.ListOptionsAll)
}
// LoadPaginatedRepositories loads paginated repositories of the team in t.Repos.
func (t *Team) LoadPaginatedRepositories(ctx context.Context, listOptions db.ListOptions) (err error) {
if t.Repos != nil {
return nil
}
t.Repos, err = GetTeamRepositories(ctx, &SearchTeamRepoOptions{
TeamID: t.ID,
ListOptions: listOptions,
TeamID: t.ID,
})
return err
}

View file

@ -413,10 +413,18 @@ func TeamRepositories(ctx *context.Context) {
return
}
if err := ctx.Org.Team.LoadRepositories(ctx); err != nil {
page := max(ctx.FormInt("page"), 1)
total := ctx.Org.Team.NumRepos
pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
opts := db.ListOptions{}
opts.Page = page
opts.PageSize = setting.UI.User.RepoPagingNum
if err := ctx.Org.Team.LoadPaginatedRepositories(ctx, opts); err != nil {
ctx.ServerError("GetRepositories", err)
return
}
ctx.Data["Page"] = pager
ctx.Data["Units"] = unit_model.Units
ctx.HTML(http.StatusOK, tplTeamRepositories)
}

View file

@ -50,6 +50,7 @@
</div>
{{end}}
</div>
{{template "base/paginate" .}}
</div>
</div>
</div>

View file

@ -46,3 +46,29 @@ func TestPaginatedMembers(t *testing.T) {
doc := NewHTMLParser(t, newVar)
assert.Contains(t, strings.TrimSpace(doc.Find("a.item.navigation:contains('Next')").AttrOr("href", "")), fmt.Sprintf("%s?page=2", teamURL))
}
func TestPaginatedRepos(t *testing.T) {
defer tests.PrepareTestEnv(t)()
// To make sure that pagination kicks in even though the test team has few repos
defer test.MockVariableValue(&setting.UI.User.RepoPagingNum, 2)()
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.GreaterOrEqual(t, team.NumRepos, 3)
isOrgMember, err := organization.IsOrganizationMember(db.DefaultContext, org.ID, user.ID)
require.NoError(t, err)
assert.True(t, isOrgMember)
isTeamMember, err := organization.IsTeamMember(db.DefaultContext, team.OrgID, team.ID, user.ID)
require.NoError(t, err)
assert.True(t, isTeamMember)
assert.Equal(t, org.ID, team.OrgID)
session := loginUser(t, user.Name)
teamURL := fmt.Sprintf("/org/%s/teams/%s/repositories", org.Name, team.LowerName)
body := session.MakeRequest(t, NewRequest(t, "GET", teamURL), http.StatusOK).Body
doc := NewHTMLParser(t, body)
assert.Contains(t, strings.TrimSpace(doc.Find("a.item.navigation:contains('Next')").AttrOr("href", "")), fmt.Sprintf("%s?page=2", teamURL))
}