|
|
@ -5,6 +5,7 @@ |
|
|
|
package repo |
|
|
|
package repo |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"net/http" |
|
|
|
"net/http" |
|
|
|
"net/url" |
|
|
|
"net/url" |
|
|
@ -299,7 +300,6 @@ func ViewProject(ctx *context.Context) { |
|
|
|
ctx.ServerError("LoadIssuesOfBoards", err) |
|
|
|
ctx.ServerError("LoadIssuesOfBoards", err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
ctx.Data["Issues"] = issueList |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
linkedPrsMap := make(map[int64][]*models.Issue) |
|
|
|
linkedPrsMap := make(map[int64][]*models.Issue) |
|
|
|
for _, issue := range issueList { |
|
|
|
for _, issue := range issueList { |
|
|
@ -547,9 +547,8 @@ func SetDefaultProjectBoard(ctx *context.Context) { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// MoveIssueAcrossBoards move a card from one board to another in a project
|
|
|
|
// MoveIssues moves or keeps issues in a column and sorts them inside that column
|
|
|
|
func MoveIssueAcrossBoards(ctx *context.Context) { |
|
|
|
func MoveIssues(ctx *context.Context) { |
|
|
|
|
|
|
|
|
|
|
|
if ctx.User == nil { |
|
|
|
if ctx.User == nil { |
|
|
|
ctx.JSON(http.StatusForbidden, map[string]string{ |
|
|
|
ctx.JSON(http.StatusForbidden, map[string]string{ |
|
|
|
"message": "Only signed in users are allowed to perform this action.", |
|
|
|
"message": "Only signed in users are allowed to perform this action.", |
|
|
@ -564,59 +563,80 @@ func MoveIssueAcrossBoards(ctx *context.Context) { |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
p, err := models.GetProjectByID(ctx.ParamsInt64(":id")) |
|
|
|
project, err := models.GetProjectByID(ctx.ParamsInt64(":id")) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
if models.IsErrProjectNotExist(err) { |
|
|
|
if models.IsErrProjectNotExist(err) { |
|
|
|
ctx.NotFound("", nil) |
|
|
|
ctx.NotFound("ProjectNotExist", nil) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
ctx.ServerError("GetProjectByID", err) |
|
|
|
ctx.ServerError("GetProjectByID", err) |
|
|
|
} |
|
|
|
} |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
if p.RepoID != ctx.Repo.Repository.ID { |
|
|
|
if project.RepoID != ctx.Repo.Repository.ID { |
|
|
|
ctx.NotFound("", nil) |
|
|
|
ctx.NotFound("InvalidRepoID", nil) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var board *models.ProjectBoard |
|
|
|
var board *models.ProjectBoard |
|
|
|
|
|
|
|
|
|
|
|
if ctx.ParamsInt64(":boardID") == 0 { |
|
|
|
if ctx.ParamsInt64(":boardID") == 0 { |
|
|
|
|
|
|
|
|
|
|
|
board = &models.ProjectBoard{ |
|
|
|
board = &models.ProjectBoard{ |
|
|
|
ID: 0, |
|
|
|
ID: 0, |
|
|
|
ProjectID: 0, |
|
|
|
ProjectID: project.ID, |
|
|
|
Title: ctx.Tr("repo.projects.type.uncategorized"), |
|
|
|
Title: ctx.Tr("repo.projects.type.uncategorized"), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
// column
|
|
|
|
board, err = models.GetProjectBoard(ctx.ParamsInt64(":boardID")) |
|
|
|
board, err = models.GetProjectBoard(ctx.ParamsInt64(":boardID")) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
if models.IsErrProjectBoardNotExist(err) { |
|
|
|
if models.IsErrProjectBoardNotExist(err) { |
|
|
|
ctx.NotFound("", nil) |
|
|
|
ctx.NotFound("ProjectBoardNotExist", nil) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
ctx.ServerError("GetProjectBoard", err) |
|
|
|
ctx.ServerError("GetProjectBoard", err) |
|
|
|
} |
|
|
|
} |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
if board.ProjectID != p.ID { |
|
|
|
if board.ProjectID != project.ID { |
|
|
|
ctx.NotFound("", nil) |
|
|
|
ctx.NotFound("BoardNotInProject", nil) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
issue, err := models.GetIssueByID(ctx.ParamsInt64(":index")) |
|
|
|
type movedIssuesForm struct { |
|
|
|
|
|
|
|
Issues []struct { |
|
|
|
|
|
|
|
IssueID int64 `json:"issueID"` |
|
|
|
|
|
|
|
Sorting int64 `json:"sorting"` |
|
|
|
|
|
|
|
} `json:"issues"` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
form := &movedIssuesForm{} |
|
|
|
|
|
|
|
if err = json.NewDecoder(ctx.Req.Body).Decode(&form); err != nil { |
|
|
|
|
|
|
|
ctx.ServerError("DecodeMovedIssuesForm", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
issueIDs := make([]int64, 0, len(form.Issues)) |
|
|
|
|
|
|
|
sortedIssueIDs := make(map[int64]int64) |
|
|
|
|
|
|
|
for _, issue := range form.Issues { |
|
|
|
|
|
|
|
issueIDs = append(issueIDs, issue.IssueID) |
|
|
|
|
|
|
|
sortedIssueIDs[issue.Sorting] = issue.IssueID |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
movedIssues, err := models.GetIssuesByIDs(issueIDs) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
if models.IsErrIssueNotExist(err) { |
|
|
|
if models.IsErrIssueNotExist(err) { |
|
|
|
ctx.NotFound("", nil) |
|
|
|
ctx.NotFound("IssueNotExisting", nil) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
ctx.ServerError("GetIssueByID", err) |
|
|
|
ctx.ServerError("GetIssueByID", err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(movedIssues) != len(form.Issues) { |
|
|
|
|
|
|
|
ctx.ServerError("IssuesNotFound", err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if err := models.MoveIssueAcrossProjectBoards(issue, board); err != nil { |
|
|
|
if err = models.MoveIssuesOnProjectBoard(board, sortedIssueIDs); err != nil { |
|
|
|
ctx.ServerError("MoveIssueAcrossProjectBoards", err) |
|
|
|
ctx.ServerError("MoveIssuesOnProjectBoard", err) |
|
|
|
return |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|