Add pagination headers on endpoints that support total count from database (#11145)
* begin work * import fmt * more work * empty commit Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
		
					parent
					
						
							
								a07cc0df76
							
						
					
				
			
			
				commit
				
					
						81324cf37c
					
				
			
		
					 9 changed files with 51 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
package admin
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
| 
						 | 
				
			
			@ -101,10 +102,12 @@ func GetAllOrgs(ctx *context.APIContext) {
 | 
			
		|||
	//   "403":
 | 
			
		||||
	//     "$ref": "#/responses/forbidden"
 | 
			
		||||
 | 
			
		||||
	users, _, err := models.SearchUsers(&models.SearchUserOptions{
 | 
			
		||||
	listOptions := utils.GetListOptions(ctx)
 | 
			
		||||
 | 
			
		||||
	users, maxResults, err := models.SearchUsers(&models.SearchUserOptions{
 | 
			
		||||
		Type:        models.UserTypeOrganization,
 | 
			
		||||
		OrderBy:     models.SearchOrderByAlphabetically,
 | 
			
		||||
		ListOptions: utils.GetListOptions(ctx),
 | 
			
		||||
		ListOptions: listOptions,
 | 
			
		||||
		Visible:     []api.VisibleType{api.VisibleTypePublic, api.VisibleTypeLimited, api.VisibleTypePrivate},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -115,5 +118,8 @@ func GetAllOrgs(ctx *context.APIContext) {
 | 
			
		|||
	for i := range users {
 | 
			
		||||
		orgs[i] = convert.ToOrganization(users[i])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
 | 
			
		||||
	ctx.JSON(http.StatusOK, &orgs)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -351,10 +351,12 @@ func GetAllUsers(ctx *context.APIContext) {
 | 
			
		|||
	//   "403":
 | 
			
		||||
	//     "$ref": "#/responses/forbidden"
 | 
			
		||||
 | 
			
		||||
	users, _, err := models.SearchUsers(&models.SearchUserOptions{
 | 
			
		||||
	listOptions := utils.GetListOptions(ctx)
 | 
			
		||||
 | 
			
		||||
	users, maxResults, err := models.SearchUsers(&models.SearchUserOptions{
 | 
			
		||||
		Type:        models.UserTypeIndividual,
 | 
			
		||||
		OrderBy:     models.SearchOrderByAlphabetically,
 | 
			
		||||
		ListOptions: utils.GetListOptions(ctx),
 | 
			
		||||
		ListOptions: listOptions,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "GetAllUsers", err)
 | 
			
		||||
| 
						 | 
				
			
			@ -366,5 +368,7 @@ func GetAllUsers(ctx *context.APIContext) {
 | 
			
		|||
		results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
 | 
			
		||||
	ctx.JSON(http.StatusOK, &results)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ import (
 | 
			
		|||
// listMembers list an organization's members
 | 
			
		||||
func listMembers(ctx *context.APIContext, publicOnly bool) {
 | 
			
		||||
	var members []*models.User
 | 
			
		||||
 | 
			
		||||
	members, _, err := models.FindOrgMembers(&models.FindOrgMembersOpts{
 | 
			
		||||
		OrgID:       ctx.Org.Organization.ID,
 | 
			
		||||
		PublicOnly:  publicOnly,
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +35,7 @@ func listMembers(ctx *context.APIContext, publicOnly bool) {
 | 
			
		|||
	for i, member := range members {
 | 
			
		||||
		apiMembers[i] = convert.ToUser(member, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusOK, apiMembers)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
package org
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/models"
 | 
			
		||||
| 
						 | 
				
			
			@ -115,8 +116,10 @@ func GetAll(ctx *context.APIContext) {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	publicOrgs, _, err := models.SearchUsers(&models.SearchUserOptions{
 | 
			
		||||
		ListOptions: utils.GetListOptions(ctx),
 | 
			
		||||
	listOptions := utils.GetListOptions(ctx)
 | 
			
		||||
 | 
			
		||||
	publicOrgs, maxResults, err := models.SearchUsers(&models.SearchUserOptions{
 | 
			
		||||
		ListOptions: listOptions,
 | 
			
		||||
		Type:        models.UserTypeOrganization,
 | 
			
		||||
		OrderBy:     models.SearchOrderByAlphabetically,
 | 
			
		||||
		Visible:     vMode,
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +133,8 @@ func GetAll(ctx *context.APIContext) {
 | 
			
		|||
		orgs[i] = convert.ToOrganization(publicOrgs[i])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
 | 
			
		||||
	ctx.JSON(http.StatusOK, &orgs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
package org
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -650,15 +651,17 @@ func SearchTeam(ctx *context.APIContext) {
 | 
			
		|||
	//           items:
 | 
			
		||||
	//             "$ref": "#/definitions/Team"
 | 
			
		||||
 | 
			
		||||
	listOptions := utils.GetListOptions(ctx)
 | 
			
		||||
 | 
			
		||||
	opts := &models.SearchTeamOptions{
 | 
			
		||||
		UserID:      ctx.User.ID,
 | 
			
		||||
		Keyword:     strings.TrimSpace(ctx.Query("q")),
 | 
			
		||||
		OrgID:       ctx.Org.Organization.ID,
 | 
			
		||||
		IncludeDesc: (ctx.Query("include_desc") == "" || ctx.QueryBool("include_desc")),
 | 
			
		||||
		ListOptions: utils.GetListOptions(ctx),
 | 
			
		||||
		ListOptions: listOptions,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	teams, _, err := models.SearchTeam(opts)
 | 
			
		||||
	teams, maxResults, err := models.SearchTeam(opts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("SearchTeam failed: %v", err)
 | 
			
		||||
		ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
 | 
			
		||||
| 
						 | 
				
			
			@ -681,6 +684,8 @@ func SearchTeam(ctx *context.APIContext) {
 | 
			
		|||
		apiTeams[i] = convert.ToTeam(teams[i])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
 | 
			
		||||
	ctx.JSON(http.StatusOK, map[string]interface{}{
 | 
			
		||||
		"ok":   true,
 | 
			
		||||
		"data": apiTeams,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -202,14 +202,16 @@ func GetAllCommits(ctx *context.APIContext) {
 | 
			
		|||
		i++
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
 | 
			
		||||
 | 
			
		||||
	// kept for backwards compatibility
 | 
			
		||||
	ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page))
 | 
			
		||||
	ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize))
 | 
			
		||||
	ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10))
 | 
			
		||||
	ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount))
 | 
			
		||||
	ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount))
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal))
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusOK, &apiCommits)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -322,6 +322,8 @@ func ListIssues(ctx *context.APIContext) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(ctx.Repo.Repository.NumIssues, listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", ctx.Repo.Repository.NumIssues))
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,8 +208,10 @@ func getCommitStatuses(ctx *context.APIContext, sha string) {
 | 
			
		|||
	}
 | 
			
		||||
	repo := ctx.Repo.Repository
 | 
			
		||||
 | 
			
		||||
	statuses, _, err := models.GetCommitStatuses(repo, sha, &models.CommitStatusOptions{
 | 
			
		||||
		ListOptions: utils.GetListOptions(ctx),
 | 
			
		||||
	listOptions := utils.GetListOptions(ctx)
 | 
			
		||||
 | 
			
		||||
	statuses, maxResults, err := models.GetCommitStatuses(repo, sha, &models.CommitStatusOptions{
 | 
			
		||||
		ListOptions: listOptions,
 | 
			
		||||
		SortType:    ctx.QueryTrim("sort"),
 | 
			
		||||
		State:       ctx.QueryTrim("state"),
 | 
			
		||||
	})
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +225,9 @@ func getCommitStatuses(ctx *context.APIContext, sha string) {
 | 
			
		|||
		apiStatuses = append(apiStatuses, status.APIFormat())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusOK, apiStatuses)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
package user
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,14 +57,16 @@ func Search(ctx *context.APIContext) {
 | 
			
		|||
	//           items:
 | 
			
		||||
	//             "$ref": "#/definitions/User"
 | 
			
		||||
 | 
			
		||||
	listOptions := utils.GetListOptions(ctx)
 | 
			
		||||
 | 
			
		||||
	opts := &models.SearchUserOptions{
 | 
			
		||||
		Keyword:     strings.Trim(ctx.Query("q"), " "),
 | 
			
		||||
		UID:         com.StrTo(ctx.Query("uid")).MustInt64(),
 | 
			
		||||
		Type:        models.UserTypeIndividual,
 | 
			
		||||
		ListOptions: utils.GetListOptions(ctx),
 | 
			
		||||
		ListOptions: listOptions,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	users, _, err := models.SearchUsers(opts)
 | 
			
		||||
	users, maxResults, err := models.SearchUsers(opts)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
 | 
			
		||||
			"ok":    false,
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +80,9 @@ func Search(ctx *context.APIContext) {
 | 
			
		|||
		results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
 | 
			
		||||
	ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults))
 | 
			
		||||
 | 
			
		||||
	ctx.JSON(http.StatusOK, map[string]interface{}{
 | 
			
		||||
		"ok":   true,
 | 
			
		||||
		"data": results,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue