mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-02 02:53:23 +09:00
refactor: pagination/pager (#39162)
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"gitea.dev/modules/git"
|
||||
"gitea.dev/modules/httpcache"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/paginator"
|
||||
"gitea.dev/modules/reqctx"
|
||||
"gitea.dev/modules/setting"
|
||||
"gitea.dev/modules/util"
|
||||
@@ -196,27 +197,26 @@ func GetAPIContext(req *http.Request) *APIContext {
|
||||
}
|
||||
|
||||
func genAPILinks(curURL *url.URL, total int64, pageSize, curPage int) []string {
|
||||
page := NewPagination(total, pageSize, curPage, 0)
|
||||
paginater := page.Paginater
|
||||
p := paginator.New(int(total), pageSize, curPage, 0)
|
||||
links := make([]string, 0, 4)
|
||||
|
||||
if paginater.HasNext() {
|
||||
if p.HasNext() {
|
||||
u := *curURL
|
||||
queries := u.Query()
|
||||
queries.Set("page", strconv.Itoa(paginater.Next()))
|
||||
queries.Set("page", strconv.Itoa(p.Next()))
|
||||
u.RawQuery = queries.Encode()
|
||||
|
||||
links = append(links, fmt.Sprintf("<%s%s>; rel=\"next\"", setting.AppURL, u.RequestURI()[1:]))
|
||||
}
|
||||
if !paginater.IsLast() {
|
||||
if !p.IsLast() {
|
||||
u := *curURL
|
||||
queries := u.Query()
|
||||
queries.Set("page", strconv.Itoa(paginater.TotalPages()))
|
||||
queries.Set("page", strconv.Itoa(p.TotalPages()))
|
||||
u.RawQuery = queries.Encode()
|
||||
|
||||
links = append(links, fmt.Sprintf("<%s%s>; rel=\"last\"", setting.AppURL, u.RequestURI()[1:]))
|
||||
}
|
||||
if !paginater.IsFirst() {
|
||||
if !p.IsFirst() {
|
||||
u := *curURL
|
||||
queries := u.Query()
|
||||
queries.Set("page", "1")
|
||||
@@ -224,10 +224,10 @@ func genAPILinks(curURL *url.URL, total int64, pageSize, curPage int) []string {
|
||||
|
||||
links = append(links, fmt.Sprintf("<%s%s>; rel=\"first\"", setting.AppURL, u.RequestURI()[1:]))
|
||||
}
|
||||
if paginater.HasPrevious() {
|
||||
if p.HasPrevious() {
|
||||
u := *curURL
|
||||
queries := u.Query()
|
||||
queries.Set("page", strconv.Itoa(paginater.Previous()))
|
||||
queries.Set("page", strconv.Itoa(p.Previous()))
|
||||
u.RawQuery = queries.Encode()
|
||||
|
||||
links = append(links, fmt.Sprintf("<%s%s>; rel=\"prev\"", setting.AppURL, u.RequestURI()[1:]))
|
||||
|
||||
@@ -13,28 +13,68 @@ import (
|
||||
"strings"
|
||||
|
||||
"gitea.dev/modules/container"
|
||||
"gitea.dev/modules/optional"
|
||||
"gitea.dev/modules/paginator"
|
||||
)
|
||||
|
||||
type PagerBuilder struct {
|
||||
ctx *Context
|
||||
total int64
|
||||
curPage int
|
||||
perPageLimit int
|
||||
navPageNum *int
|
||||
}
|
||||
|
||||
func NewPagerBuilder(ctx *Context) *PagerBuilder {
|
||||
return &PagerBuilder{ctx: ctx}
|
||||
}
|
||||
|
||||
func (pb *PagerBuilder) TotalCount(n int64) *PagerBuilder {
|
||||
pb.total = n
|
||||
return pb
|
||||
}
|
||||
|
||||
func (pb *PagerBuilder) PerPageLimit(n int) *PagerBuilder {
|
||||
pb.perPageLimit = n
|
||||
return pb
|
||||
}
|
||||
|
||||
func (pb *PagerBuilder) CurPage(n int) *PagerBuilder {
|
||||
pb.curPage = n
|
||||
return pb
|
||||
}
|
||||
|
||||
func (pb *PagerBuilder) NavPageNum(n int) *PagerBuilder {
|
||||
pb.navPageNum = &n
|
||||
return pb
|
||||
}
|
||||
|
||||
func (pb *PagerBuilder) Build() *Pagination {
|
||||
navPageNum := optional.FromPtr(pb.navPageNum).ValueOrDefault(5)
|
||||
p := newPagination(pb.total, pb.perPageLimit, pb.curPage, navPageNum)
|
||||
p.AddParamFromRequest(pb.ctx.Req)
|
||||
return p
|
||||
}
|
||||
|
||||
// Pagination provides a pagination via paginator.Paginator and additional configurations for the link params used in rendering
|
||||
type Pagination struct {
|
||||
Paginater *paginator.Paginator
|
||||
Paginator *paginator.Paginator
|
||||
urlParams []string
|
||||
}
|
||||
|
||||
// NewPagination creates a new instance of the Pagination struct.
|
||||
// newPagination creates a new instance of the Pagination struct.
|
||||
// "total" is usually from database result "count int64", so it also uses int64
|
||||
// "pagingNum" is "page size" or "limit", "current" is "page"
|
||||
// total=-1 means only showing prev/next
|
||||
func NewPagination(total int64, pagingNum, current, numPages int) *Pagination {
|
||||
func newPagination(total int64, pagingNum, current, numPages int) *Pagination {
|
||||
totalInt := int(min(total, int64(math.MaxInt)))
|
||||
p := &Pagination{}
|
||||
p.Paginater = paginator.New(totalInt, pagingNum, current, numPages)
|
||||
p.Paginator = paginator.New(totalInt, pagingNum, current, numPages)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Pagination) WithUnlimitedPaging(curRows int, hasNext bool) *Pagination {
|
||||
p.Paginater.SetUnlimitedPaging(curRows, hasNext)
|
||||
p.Paginator.SetUnlimitedPaging(curRows, hasNext)
|
||||
return p
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
func TestPagination(t *testing.T) {
|
||||
p := NewPagination(1, 1, 1, 1)
|
||||
p := newPagination(1, 1, 1, 1)
|
||||
params := url.Values{}
|
||||
params.Add("k1", "11")
|
||||
params.Add("k1", "12")
|
||||
@@ -33,23 +33,23 @@ func TestPagination(t *testing.T) {
|
||||
v, _ = url.ParseQuery(string(p.GetParams()))
|
||||
assert.Equal(t, params, v)
|
||||
|
||||
p = NewPagination(-1, 1, 1, 1)
|
||||
p = newPagination(-1, 1, 1, 1)
|
||||
p.WithUnlimitedPaging(0, false)
|
||||
assert.Zero(t, p.Paginater.TotalPages())
|
||||
assert.False(t, p.Paginater.HasNext())
|
||||
assert.Zero(t, p.Paginator.TotalPages())
|
||||
assert.False(t, p.Paginator.HasNext())
|
||||
|
||||
p = NewPagination(-1, 1, 1, 1)
|
||||
p = newPagination(-1, 1, 1, 1)
|
||||
p.WithUnlimitedPaging(10, false)
|
||||
assert.Equal(t, 1, p.Paginater.TotalPages()) // first page, no next, so it should know that the total page number is 1
|
||||
assert.False(t, p.Paginater.HasNext())
|
||||
assert.Equal(t, 1, p.Paginator.TotalPages()) // first page, no next, so it should know that the total page number is 1
|
||||
assert.False(t, p.Paginator.HasNext())
|
||||
|
||||
p = NewPagination(-1, 1, 2, 1)
|
||||
p = newPagination(-1, 1, 2, 1)
|
||||
p.WithUnlimitedPaging(10, false)
|
||||
assert.Equal(t, -1, p.Paginater.TotalPages())
|
||||
assert.False(t, p.Paginater.HasNext())
|
||||
assert.Equal(t, -1, p.Paginator.TotalPages())
|
||||
assert.False(t, p.Paginator.HasNext())
|
||||
|
||||
p = NewPagination(-1, 1, 1, 1)
|
||||
p = newPagination(-1, 1, 1, 1)
|
||||
p.WithUnlimitedPaging(10, true)
|
||||
assert.Equal(t, -1, p.Paginater.TotalPages())
|
||||
assert.True(t, p.Paginater.HasNext())
|
||||
assert.Equal(t, -1, p.Paginator.TotalPages())
|
||||
assert.True(t, p.Paginator.HasNext())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user