318 lines
7.5 KiB
Go
318 lines
7.5 KiB
Go
// Copyright 2023 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package projects
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
issues_model "code.gitea.io/gitea/models/issues"
|
|
project_model "code.gitea.io/gitea/models/project"
|
|
"code.gitea.io/gitea/modules/context"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
api "code.gitea.io/gitea/modules/structs"
|
|
"code.gitea.io/gitea/modules/web"
|
|
"code.gitea.io/gitea/services/convert"
|
|
)
|
|
|
|
func ListProjectBoards(ctx *context.APIContext) {
|
|
// swagger:operation GET /projects/{projectId}/boards board boardGetProjectBoards
|
|
// ---
|
|
// summary: Get project boards
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: projectId
|
|
// in: path
|
|
// description: id of the project
|
|
// type: string
|
|
// required: true
|
|
// - 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/ProjectBoardList"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
project_id := ctx.ParamsInt64(":projectId")
|
|
project, err := project_model.GetProjectByID(ctx, project_id)
|
|
if err != nil {
|
|
ctx.Error(http.StatusNotFound, "ListProjectBoards", err)
|
|
return
|
|
}
|
|
|
|
boards, count, err := project.GetBoardsAndCount(ctx)
|
|
if err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
ctx.SetLinkHeader(int(count), setting.UI.IssuePagingNum)
|
|
ctx.SetTotalCountHeader(count)
|
|
|
|
apiBoards, err := convert.ToApiProjectBoardList(ctx, boards)
|
|
if err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
ctx.JSON(200, apiBoards)
|
|
|
|
}
|
|
|
|
// ProjectBoardCard represents an issue card on a project board.
|
|
type ProjectBoardCard struct {
|
|
ID int64 `json:"id"`
|
|
Issue *api.Issue `json:"issue,omitempty"`
|
|
}
|
|
|
|
func ListProjectBoardCards(ctx *context.APIContext) {
|
|
// swagger:operation GET /projects/{projectId}/boards/{boardId}/cards board boardGetProjectBoardCards
|
|
// ---
|
|
// summary: Get project board cards
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: projectId
|
|
// in: path
|
|
// description: id of the project
|
|
// type: string
|
|
// required: true
|
|
// - name: boardId
|
|
// in: path
|
|
// description: id of the board
|
|
// type: string
|
|
// required: true
|
|
// responses:
|
|
// "200":
|
|
// "description": "Project board cards"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
projectID := ctx.ParamsInt64(":projectId")
|
|
project, err := project_model.GetProjectByID(ctx, projectID)
|
|
if err != nil {
|
|
ctx.Error(http.StatusNotFound, "ListProjectBoardCards", err)
|
|
return
|
|
}
|
|
|
|
boardID := ctx.ParamsInt64(":boardId")
|
|
var board *project_model.Board
|
|
if boardID == 0 {
|
|
board = &project_model.Board{
|
|
ID: 0,
|
|
ProjectID: project.ID,
|
|
Default: true,
|
|
Title: "Uncategorized",
|
|
}
|
|
} else {
|
|
board, err = project_model.GetBoard(ctx, boardID)
|
|
if err != nil {
|
|
ctx.Error(http.StatusNotFound, "GetProjectBoard", err)
|
|
return
|
|
}
|
|
if board.ProjectID != project.ID {
|
|
ctx.NotFound("BoardNotInProject", nil)
|
|
return
|
|
}
|
|
}
|
|
|
|
issues, err := issues_model.LoadIssuesFromBoard(ctx, board)
|
|
if err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
cards := make([]*ProjectBoardCard, 0, len(issues))
|
|
for _, issue := range issues {
|
|
cards = append(cards, &ProjectBoardCard{
|
|
ID: issue.ID,
|
|
Issue: convert.ToAPIIssue(ctx, issue),
|
|
})
|
|
}
|
|
ctx.JSON(http.StatusOK, cards)
|
|
}
|
|
|
|
func CreateProjectBoard(ctx *context.APIContext) {
|
|
// swagger:operation POST /projects/{projectId}/boards board boardCreateProjectBoard
|
|
// ---
|
|
// summary: Create project board
|
|
// produces:
|
|
// - application/json
|
|
// consumes:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: projectId
|
|
// in: path
|
|
// description: id of the project
|
|
// type: string
|
|
// required: true
|
|
// - name: board
|
|
// in: body
|
|
// required: true
|
|
// schema: { "$ref": "#/definitions/NewProjectBoardPayload" }
|
|
//
|
|
// responses:
|
|
//
|
|
// "201":
|
|
// "$ref": "#/responses/ProjectBoard"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
form := web.GetForm(ctx).(*api.NewProjectBoardPayload)
|
|
|
|
board := &project_model.Board{
|
|
Title: form.Title,
|
|
Default: form.Default,
|
|
Sorting: form.Sorting,
|
|
Color: form.Color,
|
|
ProjectID: ctx.ParamsInt64(":projectId"),
|
|
CreatorID: ctx.Doer.ID,
|
|
}
|
|
|
|
if err := project_model.NewBoard(ctx, board); err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
board, err := project_model.GetBoard(ctx, board.ID)
|
|
if err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusCreated, convert.ToAPIProjectBoard(ctx, board))
|
|
}
|
|
|
|
func GetProjectBoard(ctx *context.APIContext) {
|
|
// swagger:operation GET /projects/boards/{boardId} board boardGetProjectBoard
|
|
// ---
|
|
// summary: Get project board
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: boardId
|
|
// in: path
|
|
// description: id of the board
|
|
// type: string
|
|
// required: true
|
|
//
|
|
// responses:
|
|
//
|
|
// "200":
|
|
// "$ref": "#/responses/ProjectBoard"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
board, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardId"))
|
|
if err != nil {
|
|
if project_model.IsErrProjectBoardNotExist(err) {
|
|
ctx.Error(http.StatusNotFound, "GetProjectBoard", err)
|
|
} else {
|
|
ctx.Error(http.StatusInternalServerError, "GetProjectBoard", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, convert.ToAPIProjectBoard(ctx, board))
|
|
}
|
|
|
|
func UpdateProjectBoard(ctx *context.APIContext) {
|
|
// swagger:operation PATCH /projects/boards/{boardId} board boardUpdateProjectBoard
|
|
// ---
|
|
// summary: Update project board
|
|
// produces:
|
|
// - application/json
|
|
// consumes:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: boardId
|
|
// in: path
|
|
// description: id of the project board
|
|
// type: string
|
|
// required: true
|
|
// - name: board
|
|
// in: body
|
|
// required: true
|
|
// schema: { "$ref": "#/definitions/UpdateProjectBoardPayload" }
|
|
//
|
|
// responses:
|
|
//
|
|
// "200":
|
|
// "$ref": "#/responses/ProjectBoard"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
|
|
form := web.GetForm(ctx).(*api.UpdateProjectBoardPayload)
|
|
|
|
board, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardId"))
|
|
if err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
if board.Title != form.Title {
|
|
board.Title = form.Title
|
|
}
|
|
if board.Color != form.Color {
|
|
board.Color = form.Color
|
|
}
|
|
|
|
if err := project_model.UpdateBoard(ctx, board); err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
board, err = project_model.GetBoard(ctx, board.ID)
|
|
if err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
ctx.JSON(200, convert.ToAPIProjectBoard(ctx, board))
|
|
}
|
|
|
|
func DeleteProjectBoard(ctx *context.APIContext) {
|
|
// swagger:operation DELETE /projects/boards/{boardId} board boardDeleteProjectBoard
|
|
// ---
|
|
// summary: Delete project board
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: boardId
|
|
// in: path
|
|
// description: id of the project board
|
|
// type: string
|
|
// required: true
|
|
//
|
|
// responses:
|
|
//
|
|
// "204":
|
|
// "description": "Project board deleted"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
if err := project_model.DeleteBoardByID(ctx, ctx.ParamsInt64(":boardId")); err != nil {
|
|
ctx.InternalServerError(err)
|
|
return
|
|
}
|
|
|
|
ctx.Status(http.StatusNoContent)
|
|
}
|