feat: add pagination support and update swagger documentation

This commit is contained in:
eyad-hussein 2024-08-01 16:02:36 +03:00
parent f3f69085d9
commit 42c54d0396
8 changed files with 157 additions and 76 deletions

View File

@ -12,15 +12,15 @@ type Column struct {
// EditProjectColumnOption options for editing a project column
type EditProjectColumnOption struct {
Title string `binding:"MaxSize(100)"`
Sorting int8
Color string `binding:"MaxSize(7)"`
Title string `json:"title" binding:"MaxSize(100)"`
Sorting int8 `json:"sorting"`
Color string `json:"color" binding:"MaxSize(7)"`
}
// CreateProjectColumnOption options for creating a project column
type CreateProjectColumnOption struct {
// required:true
Title string `binding:"Required;MaxSize(100)"`
Sorting int8
Color string `binding:"MaxSize(7)"`
Title string `json:"title" binding:"Required;MaxSize(100)"`
Sorting int8 `json:"sorting"`
Color string `json:"color" binding:"MaxSize(7)"`
}

View File

@ -1158,7 +1158,7 @@ func Routes() *web.Router {
m.Group("", func() {
m.Patch("", bind(api.EditProjectColumnOption{}), project.EditProjectColumn)
m.Delete("", project.DeleteProjectColumn)
m.Post("/default", project.SetDefaultProjectColumn)
m.Put("/default", project.SetDefaultProjectColumn)
}, reqRepoWriter(unit.TypeProjects), mustNotBeArchived, reqUnitAccess(unit.TypeProjects, perm.AccessModeWrite, true), reqProjectOwner())
})
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization, auth_model.AccessTokenScopeCategoryRepository), reqToken(), projectIDAssignmentAPI(), columnAssignment(), individualPermsChecker, reqRepoReader(unit.TypeProjects), mustEnableRepoProjects, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead, true))

View File

@ -12,13 +12,14 @@ import (
"code.gitea.io/gitea/modules/optional"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
)
// CreateProject creates a new project for organization
func CreateProject(ctx *context.APIContext) {
// swagger:operation POST /orgs/{org}/projects project createProject
// swagger:operation POST /orgs/{org}/projects project orgCreateProject
// ---
// summary: Create a new project
// consumes:
@ -71,7 +72,7 @@ func CreateProject(ctx *context.APIContext) {
// GetProjects returns a list of projects that belong to an organization
func GetProjects(ctx *context.APIContext) {
// swagger:operation GET /orgs/{org}/projects project getProjects
// swagger:operation GET /orgs/{org}/projects project orgGetProjects
// ---
// summary: Get a list of projects
// produces:
@ -82,6 +83,14 @@ func GetProjects(ctx *context.APIContext) {
// description: organization name that the project belongs to
// required: true
// type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/ProjectList"
@ -92,23 +101,27 @@ func GetProjects(ctx *context.APIContext) {
// "423":
// "$ref": "#/responses/repoArchivedError"
listOptions := utils.GetListOptions(ctx)
sortType := ctx.FormTrim("sort")
isShowClosed := strings.ToLower(ctx.FormTrim("state")) == "closed"
searchOptions := project_model.SearchOptions{
IsClosed: optional.Some(isShowClosed),
OrderBy: project_model.GetSearchOrderByBySortType(sortType),
OwnerID: ctx.ContextUser.ID,
Type: project_model.TypeOrganization,
ListOptions: listOptions,
IsClosed: optional.Some(isShowClosed),
OrderBy: project_model.GetSearchOrderByBySortType(sortType),
OwnerID: ctx.ContextUser.ID,
Type: project_model.TypeOrganization,
}
projects, err := db.Find[project_model.Project](ctx, &searchOptions)
projects, maxResults, err := db.FindAndCount[project_model.Project](ctx, &searchOptions)
if err != nil {
ctx.ServerError("FindProjects", err)
ctx.Error(http.StatusInternalServerError, "db.FindAndCount[project_model.Project]", err)
return
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
ctx.SetTotalCountHeader(maxResults)
ctx.JSON(http.StatusOK, convert.ToProjects(ctx, projects))
}

View File

@ -16,7 +16,7 @@ import (
// GetProject returns a project
func GetProject(ctx *context.APIContext) {
// swagger:operation GET /projects/{project_id} project getProject
// swagger:operation GET /projects/{project_id} project projectGetProject
// ---
// summary: Get a project
// produces:
@ -73,7 +73,7 @@ func GetProject(ctx *context.APIContext) {
// EditProject edits a project
func EditProject(ctx *context.APIContext) {
// swagger:operation PATCH /projects/{project_id} project editProject
// swagger:operation PATCH /projects/{project_id} project projectEditProject
// ---
// summary: Edit a project
// produces:
@ -119,7 +119,7 @@ func EditProject(ctx *context.APIContext) {
// DeleteProject deletes a project
func DeleteProject(ctx *context.APIContext) {
// swagger:operation DELETE /projects/{project_id} project deleteProject
// swagger:operation DELETE /projects/{project_id} project projectDeleteProject
// ---
// summary: Delete a project
// description: Deletes a specific project for a given user and repository.
@ -151,7 +151,7 @@ func DeleteProject(ctx *context.APIContext) {
// ChangeProjectStatus updates the status of a project between "open" and "close"
func ChangeProjectStatus(ctx *context.APIContext) {
// swagger:operation PATCH /projects/{project_id}/{action} project changeProjectStatus
// swagger:operation PATCH /projects/{project_id}/{action} project projectProjectChangeProjectStatus
// ---
// summary: Change the status of a project
// produces:

View File

@ -18,7 +18,7 @@ import (
// GetProjectColumn returns a project column
func GetProjectColumn(ctx *context.APIContext) {
// swagger:operation GET /projects/columns/{column_id} project getProject
// swagger:operation GET /projects/columns/{column_id} project projectGetProjectColumn
// ---
// summary: Get a project column
// produces:
@ -51,7 +51,7 @@ func GetProjectColumn(ctx *context.APIContext) {
// GetProjectColumns returns a list of project columns
func GetProjectColumns(ctx *context.APIContext) {
// swagger:operation GET /projects/{project_id}/columns project getProject
// swagger:operation GET /projects/{project_id}/columns project projectGetProjectColumns
// ---
// summary: Get a list of project columns
// produces:
@ -91,7 +91,7 @@ func GetProjectColumns(ctx *context.APIContext) {
// AddColumnToProject adds a new column to a project
func AddColumnToProject(ctx *context.APIContext) {
// swagger:operation POST /projects/{project_id}/columns project addColumnToProject
// swagger:operation POST /projects/{project_id}/columns project projectAddColumnToProject
// ---
// summary: Add a column to a project
// consumes:
@ -153,7 +153,7 @@ func AddColumnToProject(ctx *context.APIContext) {
// EditProjectColumn edits a project column
func EditProjectColumn(ctx *context.APIContext) {
// swagger:operation PATCH /projects/columns/{column_id} project editProjectColumn
// swagger:operation PATCH /projects/columns/{column_id} project projectEditProjectColumn
// ---
// summary: Edit a project column
// consumes:
@ -212,7 +212,7 @@ func EditProjectColumn(ctx *context.APIContext) {
// DeleteProjectColumn deletes a project column
func DeleteProjectColumn(ctx *context.APIContext) {
// swagger:operation DELETE /projects/columns/{column_id} project deleteProjectColumn
// swagger:operation DELETE /projects/columns/{column_id} project projectDeleteProjectColumn
// ---
// summary: Delete a project column
// parameters:
@ -241,7 +241,7 @@ func DeleteProjectColumn(ctx *context.APIContext) {
// SetDefaultProjectColumn set default column for issues/pulls
func SetDefaultProjectColumn(ctx *context.APIContext) {
// swagger:operation PUT /projects/columns/{column_id}/default project setDefaultProjectColumn
// swagger:operation PUT /projects/columns/{column_id}/default project projectSetDefaultProjectColumn
// ---
// summary: Set default column for issues/pulls
// parameters:
@ -276,7 +276,7 @@ func SetDefaultProjectColumn(ctx *context.APIContext) {
// MoveColumns moves or keeps columns in a project and sorts them inside that project
func MoveColumns(ctx *context.APIContext) {
// swagger:operation PATCH /projects/{project_id}/columns/move project moveColumns
// swagger:operation PATCH /projects/{project_id}/columns/move project projectMoveColumns
// ---
// summary: Move columns in a project
// consumes:
@ -337,7 +337,7 @@ func MoveColumns(ctx *context.APIContext) {
// MoveIssues moves or keeps issues in a column and sorts them inside that column
func MoveIssues(ctx *context.APIContext) {
// swagger:operation PATCH /projects/{project_id}/columns/{column_id}/move project moveIssues
// swagger:operation PATCH /projects/{project_id}/columns/{column_id}/move project projectMoveIssues
// ---
// summary: Move issues in a column
// consumes:

View File

@ -17,13 +17,14 @@ import (
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/utils"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
)
// GetProjects returns a list of projects for a given user and repository.
func GetProjects(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{reponame}/projects project getProjects
// swagger:operation GET /repos/{owner}/{reponame}/projects project repoGetProjects
// ---
// summary: Get a list of projects
// description: Returns a list of projects for a given user and repository.
@ -40,6 +41,14 @@ func GetProjects(ctx *context.APIContext) {
// description: repository name.
// required: true
// type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/ProjectList"
@ -50,30 +59,34 @@ func GetProjects(ctx *context.APIContext) {
// "423":
// "$ref": "#/responses/repoArchivedError"
listOptions := utils.GetListOptions(ctx)
sortType := ctx.FormTrim("sort")
isShowClosed := strings.ToLower(ctx.FormTrim("state")) == "closed"
searchOptions := project_model.SearchOptions{
IsClosed: optional.Some(isShowClosed),
OrderBy: project_model.GetSearchOrderByBySortType(sortType),
RepoID: ctx.Repo.Repository.ID,
Type: project_model.TypeRepository,
ListOptions: listOptions,
IsClosed: optional.Some(isShowClosed),
OrderBy: project_model.GetSearchOrderByBySortType(sortType),
RepoID: ctx.Repo.Repository.ID,
Type: project_model.TypeRepository,
}
projects, err := db.Find[project_model.Project](ctx, &searchOptions)
projects, maxResults, err := db.FindAndCount[project_model.Project](ctx, &searchOptions)
if err != nil {
ctx.ServerError("FindProjects", err)
ctx.Error(http.StatusInternalServerError, "db.FindAndCount[project_model.Project]", err)
return
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
ctx.SetTotalCountHeader(maxResults)
ctx.JSON(http.StatusOK, convert.ToProjects(ctx, projects))
}
// CreateProject creates a new project
func CreateProject(ctx *context.APIContext) {
// swagger:operation POST /repos/{owner}/{reponame}/projects project createProject
// swagger:operation POST /repos/{owner}/{reponame}/projects project repoCreateProject
// ---
// summary: Create a new project
// description: Creates a new project for a given user and repository.
@ -132,7 +145,7 @@ func CreateProject(ctx *context.APIContext) {
// UpdateIssueProject change an issue's project to another project in a repository
func UpdateIssueProject(ctx *context.APIContext) {
// swagger:operation PUT /repos/{owner}/{reponame}/projects/{type} project updateIssueProject
// swagger:operation PUT /repos/{owner}/{reponame}/projects/{type} project repoUpdateIssueProject
// ---
// summary: Change an issue's project
// consumes:

View File

@ -12,13 +12,14 @@ import (
"code.gitea.io/gitea/modules/optional"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
)
// CreateProject creates a new project for a user
func CreateProject(ctx *context.APIContext) {
// swagger:operation POST /user/projects project createProject
// swagger:operation POST /user/projects project userCreateProject
// ---
// summary: Create a new project for user
// consumes:
@ -66,7 +67,7 @@ func CreateProject(ctx *context.APIContext) {
// GetProjects returns a list of projects that belong to a user
func GetProjects(ctx *context.APIContext) {
// swagger:operation GET /users/{username}/projects project getProjects
// swagger:operation GET /users/{username}/projects project userGetProjects
// ---
// summary: Get a list of projects
// produces:
@ -77,6 +78,14 @@ func GetProjects(ctx *context.APIContext) {
// description: owner of the project
// required: true
// type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/ProjectList"
@ -87,23 +96,27 @@ func GetProjects(ctx *context.APIContext) {
// "423":
// "$ref": "#/responses/repoArchivedError"
listOptions := utils.GetListOptions(ctx)
sortType := ctx.FormTrim("sort")
isShowClosed := strings.ToLower(ctx.FormTrim("state")) == "closed"
searchOptions := project_model.SearchOptions{
IsClosed: optional.Some(isShowClosed),
OrderBy: project_model.GetSearchOrderByBySortType(sortType),
OwnerID: ctx.ContextUser.ID,
Type: project_model.TypeIndividual,
ListOptions: listOptions,
IsClosed: optional.Some(isShowClosed),
OrderBy: project_model.GetSearchOrderByBySortType(sortType),
OwnerID: ctx.ContextUser.ID,
Type: project_model.TypeIndividual,
}
projects, err := db.Find[project_model.Project](ctx, &searchOptions)
projects, maxResults, err := db.FindAndCount[project_model.Project](ctx, &searchOptions)
if err != nil {
ctx.ServerError("FindProjects", err)
ctx.Error(http.StatusInternalServerError, "db.FindAndCount[project_model.Project]", err)
return
}
ctx.SetLinkHeader(int(maxResults), listOptions.PageSize)
ctx.SetTotalCountHeader(maxResults)
ctx.JSON(http.StatusOK, convert.ToProjects(ctx, projects))
}

View File

@ -2840,7 +2840,7 @@
"project"
],
"summary": "Get a list of projects",
"operationId": "getProjects",
"operationId": "orgGetProjects",
"parameters": [
{
"type": "string",
@ -2848,6 +2848,18 @@
"name": "org",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "page number of results to return (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "page size of results",
"name": "limit",
"in": "query"
}
],
"responses": {
@ -2876,7 +2888,7 @@
"project"
],
"summary": "Create a new project",
"operationId": "createProject",
"operationId": "orgCreateProject",
"parameters": [
{
"type": "string",
@ -3524,7 +3536,7 @@
"project"
],
"summary": "Get a project column",
"operationId": "getProject",
"operationId": "projectGetProjectColumn",
"parameters": [
{
"type": "integer",
@ -3554,7 +3566,7 @@
"project"
],
"summary": "Delete a project column",
"operationId": "deleteProjectColumn",
"operationId": "projectDeleteProjectColumn",
"parameters": [
{
"type": "integer",
@ -3590,7 +3602,7 @@
"project"
],
"summary": "Edit a project column",
"operationId": "editProjectColumn",
"operationId": "projectEditProjectColumn",
"parameters": [
{
"type": "integer",
@ -3637,7 +3649,7 @@
"project"
],
"summary": "Set default column for issues/pulls",
"operationId": "setDefaultProjectColumn",
"operationId": "projectSetDefaultProjectColumn",
"parameters": [
{
"type": "integer",
@ -3672,7 +3684,7 @@
"project"
],
"summary": "Get a project",
"operationId": "getProject",
"operationId": "projectGetProject",
"parameters": [
{
"type": "integer",
@ -3703,7 +3715,7 @@
"project"
],
"summary": "Delete a project",
"operationId": "deleteProject",
"operationId": "projectDeleteProject",
"parameters": [
{
"type": "integer",
@ -3736,7 +3748,7 @@
"project"
],
"summary": "Edit a project",
"operationId": "editProject",
"operationId": "projectEditProject",
"parameters": [
{
"type": "integer",
@ -3774,7 +3786,7 @@
"project"
],
"summary": "Get a list of project columns",
"operationId": "getProject",
"operationId": "projectGetProjectColumns",
"parameters": [
{
"type": "integer",
@ -3810,7 +3822,7 @@
"project"
],
"summary": "Add a column to a project",
"operationId": "addColumnToProject",
"operationId": "projectAddColumnToProject",
"parameters": [
{
"type": "integer",
@ -3860,7 +3872,7 @@
"project"
],
"summary": "Move columns in a project",
"operationId": "moveColumns",
"operationId": "projectMoveColumns",
"parameters": [
{
"type": "integer",
@ -3904,7 +3916,7 @@
"project"
],
"summary": "Move issues in a column",
"operationId": "moveIssues",
"operationId": "projectMoveIssues",
"parameters": [
{
"type": "integer",
@ -3955,7 +3967,7 @@
"project"
],
"summary": "Change the status of a project",
"operationId": "changeProjectStatus",
"operationId": "projectProjectChangeProjectStatus",
"parameters": [
{
"type": "integer",
@ -4292,7 +4304,7 @@
"project"
],
"summary": "Get a list of projects",
"operationId": "getProjects",
"operationId": "repoGetProjects",
"parameters": [
{
"type": "string",
@ -4307,6 +4319,18 @@
"name": "reponame",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "page number of results to return (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "page size of results",
"name": "limit",
"in": "query"
}
],
"responses": {
@ -4336,7 +4360,7 @@
"project"
],
"summary": "Create a new project",
"operationId": "createProject",
"operationId": "repoCreateProject",
"parameters": [
{
"type": "string",
@ -4390,7 +4414,7 @@
"project"
],
"summary": "Change an issue's project",
"operationId": "updateIssueProject",
"operationId": "repoUpdateIssueProject",
"parameters": [
{
"type": "string",
@ -17845,7 +17869,7 @@
"project"
],
"summary": "Create a new project for user",
"operationId": "createProject",
"operationId": "userCreateProject",
"parameters": [
{
"description": "Project data",
@ -18717,7 +18741,7 @@
"project"
],
"summary": "Get a list of projects",
"operationId": "getProjects",
"operationId": "userGetProjects",
"parameters": [
{
"type": "string",
@ -18725,6 +18749,18 @@
"name": "username",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "page number of results to return (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "page size of results",
"name": "limit",
"in": "query"
}
],
"responses": {
@ -20765,18 +20801,21 @@
"description": "CreateProjectColumnOption options for creating a project column",
"type": "object",
"required": [
"Title"
"title"
],
"properties": {
"Color": {
"type": "string"
"color": {
"type": "string",
"x-go-name": "Color"
},
"Sorting": {
"sorting": {
"type": "integer",
"format": "int8"
"format": "int8",
"x-go-name": "Sorting"
},
"Title": {
"type": "string"
"title": {
"type": "string",
"x-go-name": "Title"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
@ -21807,15 +21846,18 @@
"description": "EditProjectColumnOption options for editing a project column",
"type": "object",
"properties": {
"Color": {
"type": "string"
"color": {
"type": "string",
"x-go-name": "Color"
},
"Sorting": {
"sorting": {
"type": "integer",
"format": "int8"
"format": "int8",
"x-go-name": "Sorting"
},
"Title": {
"type": "string"
"title": {
"type": "string",
"x-go-name": "Title"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"