mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Rename project board -> column to make the UI less confusing (#30170)
This PR split the `Board` into two parts. One is the struct has been renamed to `Column` and the second we have a `Template Type`. But to make it easier to review, this PR will not change the database schemas, they are just renames. The database schema changes could be in future PRs. --------- Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: yp05327 <576951401@qq.com>
This commit is contained in:
@@ -34,7 +34,7 @@ const (
|
||||
// MustEnableProjects check if projects are enabled in settings
|
||||
func MustEnableProjects(ctx *context.Context) {
|
||||
if unit.TypeProjects.UnitGlobalDisabled() {
|
||||
ctx.NotFound("EnableKanbanBoard", nil)
|
||||
ctx.NotFound("EnableProjects", nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func MustEnableProjects(ctx *context.Context) {
|
||||
// Projects renders the home page of projects
|
||||
func Projects(ctx *context.Context) {
|
||||
shared_user.PrepareContextForProfileBigAvatar(ctx)
|
||||
ctx.Data["Title"] = ctx.Tr("repo.project_board")
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects")
|
||||
|
||||
sortType := ctx.FormTrim("sort")
|
||||
|
||||
@@ -139,7 +139,7 @@ func canWriteProjects(ctx *context.Context) bool {
|
||||
// RenderNewProject render creating a project page
|
||||
func RenderNewProject(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
||||
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||
ctx.Data["TemplateConfigs"] = project_model.GetTemplateConfigs()
|
||||
ctx.Data["CardTypes"] = project_model.GetCardConfig()
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
ctx.Data["PageIsViewProjects"] = true
|
||||
@@ -168,12 +168,12 @@ func NewProjectPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
newProject := project_model.Project{
|
||||
OwnerID: ctx.ContextUser.ID,
|
||||
Title: form.Title,
|
||||
Description: form.Content,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
BoardType: form.BoardType,
|
||||
CardType: form.CardType,
|
||||
OwnerID: ctx.ContextUser.ID,
|
||||
Title: form.Title,
|
||||
Description: form.Content,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
TemplateType: form.TemplateType,
|
||||
CardType: form.CardType,
|
||||
}
|
||||
|
||||
if ctx.ContextUser.IsOrganization() {
|
||||
@@ -314,7 +314,7 @@ func EditProjectPost(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// ViewProject renders the project board for a project
|
||||
// ViewProject renders the project with board view for a project
|
||||
func ViewProject(ctx *context.Context) {
|
||||
project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
@@ -326,15 +326,15 @@ func ViewProject(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
boards, err := project.GetBoards(ctx)
|
||||
columns, err := project.GetColumns(ctx)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoards", err)
|
||||
ctx.ServerError("GetProjectColumns", err)
|
||||
return
|
||||
}
|
||||
|
||||
issuesMap, err := issues_model.LoadIssuesFromBoardList(ctx, boards)
|
||||
issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns)
|
||||
if err != nil {
|
||||
ctx.ServerError("LoadIssuesOfBoards", err)
|
||||
ctx.ServerError("LoadIssuesOfColumns", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -377,7 +377,7 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
|
||||
ctx.Data["Project"] = project
|
||||
ctx.Data["IssuesMap"] = issuesMap
|
||||
ctx.Data["Columns"] = boards // TODO: rename boards to columns in backend
|
||||
ctx.Data["Columns"] = columns
|
||||
shared_user.RenderUserHeader(ctx)
|
||||
|
||||
err = shared_user.LoadHeaderCount(ctx)
|
||||
@@ -389,8 +389,8 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplProjectsView)
|
||||
}
|
||||
|
||||
// DeleteProjectBoard allows for the deletion of a project board
|
||||
func DeleteProjectBoard(ctx *context.Context) {
|
||||
// DeleteProjectColumn allows for the deletion of a project column
|
||||
func DeleteProjectColumn(ctx *context.Context) {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
@@ -404,36 +404,36 @@ func DeleteProjectBoard(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
pb, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardID"))
|
||||
pb, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
ctx.ServerError("GetProjectColumn", err)
|
||||
return
|
||||
}
|
||||
if pb.ProjectID != ctx.ParamsInt64(":id") {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Project[%d] as expected", pb.ID, project.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", pb.ID, project.ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if project.OwnerID != ctx.ContextUser.ID {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Owner[%d] as expected", pb.ID, ctx.ContextUser.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Owner[%d] as expected", pb.ID, ctx.ContextUser.ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := project_model.DeleteBoardByID(ctx, ctx.ParamsInt64(":boardID")); err != nil {
|
||||
ctx.ServerError("DeleteProjectBoardByID", err)
|
||||
if err := project_model.DeleteColumnByID(ctx, ctx.ParamsInt64(":columnID")); err != nil {
|
||||
ctx.ServerError("DeleteProjectColumnByID", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
// AddBoardToProjectPost allows a new board to be added to a project.
|
||||
func AddBoardToProjectPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectBoardForm)
|
||||
// AddColumnToProjectPost allows a new column to be added to a project.
|
||||
func AddColumnToProjectPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectColumnForm)
|
||||
|
||||
project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
@@ -441,21 +441,21 @@ func AddBoardToProjectPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := project_model.NewBoard(ctx, &project_model.Board{
|
||||
if err := project_model.NewColumn(ctx, &project_model.Column{
|
||||
ProjectID: project.ID,
|
||||
Title: form.Title,
|
||||
Color: form.Color,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
}); err != nil {
|
||||
ctx.ServerError("NewProjectBoard", err)
|
||||
ctx.ServerError("NewProjectColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
// CheckProjectBoardChangePermissions check permission
|
||||
func CheckProjectBoardChangePermissions(ctx *context.Context) (*project_model.Project, *project_model.Board) {
|
||||
// CheckProjectColumnChangePermissions check permission
|
||||
func CheckProjectColumnChangePermissions(ctx *context.Context) (*project_model.Project, *project_model.Column) {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
@@ -469,62 +469,60 @@ func CheckProjectBoardChangePermissions(ctx *context.Context) (*project_model.Pr
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
board, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardID"))
|
||||
column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
ctx.ServerError("GetProjectColumn", err)
|
||||
return nil, nil
|
||||
}
|
||||
if board.ProjectID != ctx.ParamsInt64(":id") {
|
||||
if column.ProjectID != ctx.ParamsInt64(":id") {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Project[%d] as expected", board.ID, project.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", column.ID, project.ID),
|
||||
})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if project.OwnerID != ctx.ContextUser.ID {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Repository[%d] as expected", board.ID, project.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Repository[%d] as expected", column.ID, project.ID),
|
||||
})
|
||||
return nil, nil
|
||||
}
|
||||
return project, board
|
||||
return project, column
|
||||
}
|
||||
|
||||
// EditProjectBoard allows a project board's to be updated
|
||||
func EditProjectBoard(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectBoardForm)
|
||||
_, board := CheckProjectBoardChangePermissions(ctx)
|
||||
// EditProjectColumn allows a project column's to be updated
|
||||
func EditProjectColumn(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectColumnForm)
|
||||
_, column := CheckProjectColumnChangePermissions(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if form.Title != "" {
|
||||
board.Title = form.Title
|
||||
column.Title = form.Title
|
||||
}
|
||||
|
||||
board.Color = form.Color
|
||||
|
||||
column.Color = form.Color
|
||||
if form.Sorting != 0 {
|
||||
board.Sorting = form.Sorting
|
||||
column.Sorting = form.Sorting
|
||||
}
|
||||
|
||||
if err := project_model.UpdateBoard(ctx, board); err != nil {
|
||||
ctx.ServerError("UpdateProjectBoard", err)
|
||||
if err := project_model.UpdateColumn(ctx, column); err != nil {
|
||||
ctx.ServerError("UpdateProjectColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
// SetDefaultProjectBoard set default board for uncategorized issues/pulls
|
||||
func SetDefaultProjectBoard(ctx *context.Context) {
|
||||
project, board := CheckProjectBoardChangePermissions(ctx)
|
||||
// SetDefaultProjectColumn set default column for uncategorized issues/pulls
|
||||
func SetDefaultProjectColumn(ctx *context.Context) {
|
||||
project, column := CheckProjectColumnChangePermissions(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := project_model.SetDefaultBoard(ctx, project.ID, board.ID); err != nil {
|
||||
ctx.ServerError("SetDefaultBoard", err)
|
||||
if err := project_model.SetDefaultColumn(ctx, project.ID, column.ID); err != nil {
|
||||
ctx.ServerError("SetDefaultColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -550,14 +548,14 @@ func MoveIssues(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
board, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardID"))
|
||||
column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
|
||||
if err != nil {
|
||||
ctx.NotFoundOrServerError("GetProjectBoard", project_model.IsErrProjectBoardNotExist, err)
|
||||
ctx.NotFoundOrServerError("GetProjectColumn", project_model.IsErrProjectColumnNotExist, err)
|
||||
return
|
||||
}
|
||||
|
||||
if board.ProjectID != project.ID {
|
||||
ctx.NotFound("BoardNotInProject", nil)
|
||||
if column.ProjectID != project.ID {
|
||||
ctx.NotFound("ColumnNotInProject", nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -602,8 +600,8 @@ func MoveIssues(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
if err = project_model.MoveIssuesOnProjectBoard(ctx, board, sortedIssueIDs); err != nil {
|
||||
ctx.ServerError("MoveIssuesOnProjectBoard", err)
|
||||
if err = project_model.MoveIssuesOnProjectColumn(ctx, column, sortedIssueIDs); err != nil {
|
||||
ctx.ServerError("MoveIssuesOnProjectColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -13,16 +13,16 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCheckProjectBoardChangePermissions(t *testing.T) {
|
||||
func TestCheckProjectColumnChangePermissions(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
ctx, _ := contexttest.MockContext(t, "user2/-/projects/4/4")
|
||||
contexttest.LoadUser(t, ctx, 2)
|
||||
ctx.ContextUser = ctx.Doer // user2
|
||||
ctx.SetParams(":id", "4")
|
||||
ctx.SetParams(":boardID", "4")
|
||||
ctx.SetParams(":columnID", "4")
|
||||
|
||||
project, board := org.CheckProjectBoardChangePermissions(ctx)
|
||||
project, column := org.CheckProjectColumnChangePermissions(ctx)
|
||||
assert.NotNil(t, project)
|
||||
assert.NotNil(t, board)
|
||||
assert.NotNil(t, column)
|
||||
assert.False(t, ctx.Written())
|
||||
}
|
||||
|
@@ -2826,12 +2826,12 @@ func ListIssues(ctx *context.Context) {
|
||||
Page: ctx.FormInt("page"),
|
||||
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
|
||||
},
|
||||
Keyword: keyword,
|
||||
RepoIDs: []int64{ctx.Repo.Repository.ID},
|
||||
IsPull: isPull,
|
||||
IsClosed: isClosed,
|
||||
ProjectBoardID: projectID,
|
||||
SortBy: issue_indexer.SortByCreatedDesc,
|
||||
Keyword: keyword,
|
||||
RepoIDs: []int64{ctx.Repo.Repository.ID},
|
||||
IsPull: isPull,
|
||||
IsClosed: isClosed,
|
||||
ProjectID: projectID,
|
||||
SortBy: issue_indexer.SortByCreatedDesc,
|
||||
}
|
||||
if since != 0 {
|
||||
searchOpt.UpdatedAfterUnix = optional.Some(since)
|
||||
|
@@ -36,7 +36,7 @@ const (
|
||||
// MustEnableRepoProjects check if repo projects are enabled in settings
|
||||
func MustEnableRepoProjects(ctx *context.Context) {
|
||||
if unit.TypeProjects.UnitGlobalDisabled() {
|
||||
ctx.NotFound("EnableKanbanBoard", nil)
|
||||
ctx.NotFound("EnableRepoProjects", nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func MustEnableRepoProjects(ctx *context.Context) {
|
||||
|
||||
// Projects renders the home page of projects
|
||||
func Projects(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.project_board")
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects")
|
||||
|
||||
sortType := ctx.FormTrim("sort")
|
||||
|
||||
@@ -132,7 +132,7 @@ func Projects(ctx *context.Context) {
|
||||
// RenderNewProject render creating a project page
|
||||
func RenderNewProject(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.projects.new")
|
||||
ctx.Data["BoardTypes"] = project_model.GetBoardConfig()
|
||||
ctx.Data["TemplateConfigs"] = project_model.GetTemplateConfigs()
|
||||
ctx.Data["CardTypes"] = project_model.GetCardConfig()
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
ctx.Data["CancelLink"] = ctx.Repo.Repository.Link() + "/projects"
|
||||
@@ -150,13 +150,13 @@ func NewProjectPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err := project_model.NewProject(ctx, &project_model.Project{
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Title: form.Title,
|
||||
Description: form.Content,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
BoardType: form.BoardType,
|
||||
CardType: form.CardType,
|
||||
Type: project_model.TypeRepository,
|
||||
RepoID: ctx.Repo.Repository.ID,
|
||||
Title: form.Title,
|
||||
Description: form.Content,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
TemplateType: form.TemplateType,
|
||||
CardType: form.CardType,
|
||||
Type: project_model.TypeRepository,
|
||||
}); err != nil {
|
||||
ctx.ServerError("NewProject", err)
|
||||
return
|
||||
@@ -289,7 +289,7 @@ func EditProjectPost(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// ViewProject renders the project board for a project
|
||||
// ViewProject renders the project with board view
|
||||
func ViewProject(ctx *context.Context) {
|
||||
project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
@@ -305,15 +305,15 @@ func ViewProject(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
boards, err := project.GetBoards(ctx)
|
||||
columns, err := project.GetColumns(ctx)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoards", err)
|
||||
ctx.ServerError("GetProjectColumns", err)
|
||||
return
|
||||
}
|
||||
|
||||
issuesMap, err := issues_model.LoadIssuesFromBoardList(ctx, boards)
|
||||
issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns)
|
||||
if err != nil {
|
||||
ctx.ServerError("LoadIssuesOfBoards", err)
|
||||
ctx.ServerError("LoadIssuesOfColumns", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ func ViewProject(ctx *context.Context) {
|
||||
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
|
||||
ctx.Data["Project"] = project
|
||||
ctx.Data["IssuesMap"] = issuesMap
|
||||
ctx.Data["Columns"] = boards // TODO: rename boards to columns in backend
|
||||
ctx.Data["Columns"] = columns
|
||||
|
||||
ctx.HTML(http.StatusOK, tplProjectsView)
|
||||
}
|
||||
@@ -406,8 +406,8 @@ func UpdateIssueProject(ctx *context.Context) {
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
// DeleteProjectBoard allows for the deletion of a project board
|
||||
func DeleteProjectBoard(ctx *context.Context) {
|
||||
// DeleteProjectColumn allows for the deletion of a project column
|
||||
func DeleteProjectColumn(ctx *context.Context) {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
@@ -432,36 +432,36 @@ func DeleteProjectBoard(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
pb, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardID"))
|
||||
pb, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
ctx.ServerError("GetProjectColumn", err)
|
||||
return
|
||||
}
|
||||
if pb.ProjectID != ctx.ParamsInt64(":id") {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Project[%d] as expected", pb.ID, project.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", pb.ID, project.ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if project.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Repository[%d] as expected", pb.ID, ctx.Repo.Repository.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Repository[%d] as expected", pb.ID, ctx.Repo.Repository.ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := project_model.DeleteBoardByID(ctx, ctx.ParamsInt64(":boardID")); err != nil {
|
||||
ctx.ServerError("DeleteProjectBoardByID", err)
|
||||
if err := project_model.DeleteColumnByID(ctx, ctx.ParamsInt64(":columnID")); err != nil {
|
||||
ctx.ServerError("DeleteProjectColumnByID", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
// AddBoardToProjectPost allows a new board to be added to a project.
|
||||
func AddBoardToProjectPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectBoardForm)
|
||||
// AddColumnToProjectPost allows a new column to be added to a project.
|
||||
func AddColumnToProjectPost(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectColumnForm)
|
||||
if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(perm.AccessModeWrite, unit.TypeProjects) {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only authorized users are allowed to perform this action.",
|
||||
@@ -479,20 +479,20 @@ func AddBoardToProjectPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := project_model.NewBoard(ctx, &project_model.Board{
|
||||
if err := project_model.NewColumn(ctx, &project_model.Column{
|
||||
ProjectID: project.ID,
|
||||
Title: form.Title,
|
||||
Color: form.Color,
|
||||
CreatorID: ctx.Doer.ID,
|
||||
}); err != nil {
|
||||
ctx.ServerError("NewProjectBoard", err)
|
||||
ctx.ServerError("NewProjectColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
func checkProjectBoardChangePermissions(ctx *context.Context) (*project_model.Project, *project_model.Board) {
|
||||
func checkProjectColumnChangePermissions(ctx *context.Context) (*project_model.Project, *project_model.Column) {
|
||||
if ctx.Doer == nil {
|
||||
ctx.JSON(http.StatusForbidden, map[string]string{
|
||||
"message": "Only signed in users are allowed to perform this action.",
|
||||
@@ -517,62 +517,60 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*project_model.Pr
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
board, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardID"))
|
||||
column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
ctx.ServerError("GetProjectColumn", err)
|
||||
return nil, nil
|
||||
}
|
||||
if board.ProjectID != ctx.ParamsInt64(":id") {
|
||||
if column.ProjectID != ctx.ParamsInt64(":id") {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Project[%d] as expected", board.ID, project.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", column.ID, project.ID),
|
||||
})
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if project.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
|
||||
"message": fmt.Sprintf("ProjectBoard[%d] is not in Repository[%d] as expected", board.ID, ctx.Repo.Repository.ID),
|
||||
"message": fmt.Sprintf("ProjectColumn[%d] is not in Repository[%d] as expected", column.ID, ctx.Repo.Repository.ID),
|
||||
})
|
||||
return nil, nil
|
||||
}
|
||||
return project, board
|
||||
return project, column
|
||||
}
|
||||
|
||||
// EditProjectBoard allows a project board's to be updated
|
||||
func EditProjectBoard(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectBoardForm)
|
||||
_, board := checkProjectBoardChangePermissions(ctx)
|
||||
// EditProjectColumn allows a project column's to be updated
|
||||
func EditProjectColumn(ctx *context.Context) {
|
||||
form := web.GetForm(ctx).(*forms.EditProjectColumnForm)
|
||||
_, column := checkProjectColumnChangePermissions(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if form.Title != "" {
|
||||
board.Title = form.Title
|
||||
column.Title = form.Title
|
||||
}
|
||||
|
||||
board.Color = form.Color
|
||||
|
||||
column.Color = form.Color
|
||||
if form.Sorting != 0 {
|
||||
board.Sorting = form.Sorting
|
||||
column.Sorting = form.Sorting
|
||||
}
|
||||
|
||||
if err := project_model.UpdateBoard(ctx, board); err != nil {
|
||||
ctx.ServerError("UpdateProjectBoard", err)
|
||||
if err := project_model.UpdateColumn(ctx, column); err != nil {
|
||||
ctx.ServerError("UpdateProjectColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONOK()
|
||||
}
|
||||
|
||||
// SetDefaultProjectBoard set default board for uncategorized issues/pulls
|
||||
func SetDefaultProjectBoard(ctx *context.Context) {
|
||||
project, board := checkProjectBoardChangePermissions(ctx)
|
||||
// SetDefaultProjectColumn set default column for uncategorized issues/pulls
|
||||
func SetDefaultProjectColumn(ctx *context.Context) {
|
||||
project, column := checkProjectColumnChangePermissions(ctx)
|
||||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := project_model.SetDefaultBoard(ctx, project.ID, board.ID); err != nil {
|
||||
ctx.ServerError("SetDefaultBoard", err)
|
||||
if err := project_model.SetDefaultColumn(ctx, project.ID, column.ID); err != nil {
|
||||
ctx.ServerError("SetDefaultColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -609,18 +607,18 @@ func MoveIssues(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
board, err := project_model.GetBoard(ctx, ctx.ParamsInt64(":boardID"))
|
||||
column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
|
||||
if err != nil {
|
||||
if project_model.IsErrProjectBoardNotExist(err) {
|
||||
ctx.NotFound("ProjectBoardNotExist", nil)
|
||||
if project_model.IsErrProjectColumnNotExist(err) {
|
||||
ctx.NotFound("ProjectColumnNotExist", nil)
|
||||
} else {
|
||||
ctx.ServerError("GetProjectBoard", err)
|
||||
ctx.ServerError("GetProjectColumn", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if board.ProjectID != project.ID {
|
||||
ctx.NotFound("BoardNotInProject", nil)
|
||||
if column.ProjectID != project.ID {
|
||||
ctx.NotFound("ColumnNotInProject", nil)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -664,8 +662,8 @@ func MoveIssues(ctx *context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
if err = project_model.MoveIssuesOnProjectBoard(ctx, board, sortedIssueIDs); err != nil {
|
||||
ctx.ServerError("MoveIssuesOnProjectBoard", err)
|
||||
if err = project_model.MoveIssuesOnProjectColumn(ctx, column, sortedIssueIDs); err != nil {
|
||||
ctx.ServerError("MoveIssuesOnProjectColumn", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -12,16 +12,16 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCheckProjectBoardChangePermissions(t *testing.T) {
|
||||
func TestCheckProjectColumnChangePermissions(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
ctx, _ := contexttest.MockContext(t, "user2/repo1/projects/1/2")
|
||||
contexttest.LoadUser(t, ctx, 2)
|
||||
contexttest.LoadRepo(t, ctx, 1)
|
||||
ctx.SetParams(":id", "1")
|
||||
ctx.SetParams(":boardID", "2")
|
||||
ctx.SetParams(":columnID", "2")
|
||||
|
||||
project, board := checkProjectBoardChangePermissions(ctx)
|
||||
project, column := checkProjectColumnChangePermissions(ctx)
|
||||
assert.NotNil(t, project)
|
||||
assert.NotNil(t, board)
|
||||
assert.NotNil(t, column)
|
||||
assert.False(t, ctx.Written())
|
||||
}
|
||||
|
@@ -1000,7 +1000,7 @@ func registerRoutes(m *web.Route) {
|
||||
m.Get("/new", org.RenderNewProject)
|
||||
m.Post("/new", web.Bind(forms.CreateProjectForm{}), org.NewProjectPost)
|
||||
m.Group("/{id}", func() {
|
||||
m.Post("", web.Bind(forms.EditProjectBoardForm{}), org.AddBoardToProjectPost)
|
||||
m.Post("", web.Bind(forms.EditProjectColumnForm{}), org.AddColumnToProjectPost)
|
||||
m.Post("/move", project.MoveColumns)
|
||||
m.Post("/delete", org.DeleteProject)
|
||||
|
||||
@@ -1008,10 +1008,10 @@ func registerRoutes(m *web.Route) {
|
||||
m.Post("/edit", web.Bind(forms.CreateProjectForm{}), org.EditProjectPost)
|
||||
m.Post("/{action:open|close}", org.ChangeProjectStatus)
|
||||
|
||||
m.Group("/{boardID}", func() {
|
||||
m.Put("", web.Bind(forms.EditProjectBoardForm{}), org.EditProjectBoard)
|
||||
m.Delete("", org.DeleteProjectBoard)
|
||||
m.Post("/default", org.SetDefaultProjectBoard)
|
||||
m.Group("/{columnID}", func() {
|
||||
m.Put("", web.Bind(forms.EditProjectColumnForm{}), org.EditProjectColumn)
|
||||
m.Delete("", org.DeleteProjectColumn)
|
||||
m.Post("/default", org.SetDefaultProjectColumn)
|
||||
m.Post("/move", org.MoveIssues)
|
||||
})
|
||||
})
|
||||
@@ -1356,7 +1356,7 @@ func registerRoutes(m *web.Route) {
|
||||
m.Get("/new", repo.RenderNewProject)
|
||||
m.Post("/new", web.Bind(forms.CreateProjectForm{}), repo.NewProjectPost)
|
||||
m.Group("/{id}", func() {
|
||||
m.Post("", web.Bind(forms.EditProjectBoardForm{}), repo.AddBoardToProjectPost)
|
||||
m.Post("", web.Bind(forms.EditProjectColumnForm{}), repo.AddColumnToProjectPost)
|
||||
m.Post("/move", project.MoveColumns)
|
||||
m.Post("/delete", repo.DeleteProject)
|
||||
|
||||
@@ -1364,10 +1364,10 @@ func registerRoutes(m *web.Route) {
|
||||
m.Post("/edit", web.Bind(forms.CreateProjectForm{}), repo.EditProjectPost)
|
||||
m.Post("/{action:open|close}", repo.ChangeProjectStatus)
|
||||
|
||||
m.Group("/{boardID}", func() {
|
||||
m.Put("", web.Bind(forms.EditProjectBoardForm{}), repo.EditProjectBoard)
|
||||
m.Delete("", repo.DeleteProjectBoard)
|
||||
m.Post("/default", repo.SetDefaultProjectBoard)
|
||||
m.Group("/{columnID}", func() {
|
||||
m.Put("", web.Bind(forms.EditProjectColumnForm{}), repo.EditProjectColumn)
|
||||
m.Delete("", repo.DeleteProjectColumn)
|
||||
m.Post("/default", repo.SetDefaultProjectColumn)
|
||||
m.Post("/move", repo.MoveIssues)
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user