diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index 35b6810786..8c731a2278 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -90,16 +90,16 @@ func LoadIssuesFromBoardList(ctx context.Context, bs project_model.BoardList) (m return issuesMap, nil } -// ChangeProjectAssign changes the project associated with an issue, if newProjectID is 0, the issue is removed from the project -func ChangeProjectAssign(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error { +// IssueAssignOrRemoveProject changes the project associated with an issue, if newProjectID is 0, the issue is removed from the project +func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error { return db.WithTx(ctx, func(ctx context.Context) error { - return addUpdateIssueProject(ctx, issue, doer, newProjectID, newColumnID) + return issueAssignOrRemoveProject(ctx, issue, doer, newProjectID, newColumnID) }) } -// addUpdateIssueProject adds or updates the project the default column associated with an issue +// issueAssignOrRemoveProject adds or updates the project the default column associated with an issue // If newProjectID is 0, the issue is removed from the project -func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error { +func issueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error { oldProjectID := issue.projectID(ctx) if err := issue.LoadRepo(ctx); err != nil { diff --git a/models/project/issue.go b/models/project/issue.go index fcc365e6af..78689efd8d 100644 --- a/models/project/issue.go +++ b/models/project/issue.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/util" ) // ProjectIssue saves relation from issue to a project @@ -79,11 +80,8 @@ func (p *Project) NumOpenIssues(ctx context.Context) int { func MoveIssuesOnProjectBoard(ctx context.Context, board *Board, sortedIssueIDs map[int64]int64) error { return db.WithTx(ctx, func(ctx context.Context) error { sess := db.GetEngine(ctx) + issueIDs := util.ValuesOfMap(sortedIssueIDs) - issueIDs := make([]int64, 0, len(sortedIssueIDs)) - for _, issueID := range sortedIssueIDs { - issueIDs = append(issueIDs, issueID) - } count, err := sess.Table(new(ProjectIssue)).Where("project_id=?", board.ProjectID).In("issue_id", issueIDs).Count() if err != nil { return err @@ -103,12 +101,38 @@ func MoveIssuesOnProjectBoard(ctx context.Context, board *Board, sortedIssueIDs } func (b *Board) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Board) error { - if b.ID == newColumn.ID { - return nil - } if b.ProjectID != newColumn.ProjectID { return fmt.Errorf("columns have to be in the same project") } - _, err := db.GetEngine(ctx).Exec("UPDATE `project_issue` SET project_board_id = ? WHERE project_board_id = ? ", newColumn.ID, b.ID) - return err + + if b.ID == newColumn.ID { + return nil + } + + var maxSorting int8 + if _, err := db.GetEngine(ctx).Select("Max(sorting)").Table("project_issue"). + Where("project_id=?", newColumn.ProjectID). + And("project_board_id=?", newColumn.ID). + Get(&maxSorting); err != nil { + return err + } + if maxSorting > 0 { + maxSorting++ + } + + issues, err := b.GetIssues(ctx) + if err != nil { + return err + } + + return db.WithTx(ctx, func(ctx context.Context) error { + for i, issue := range issues { + issue.ProjectBoardID = newColumn.ID + issue.Sorting = int64(maxSorting) + int64(i) + if _, err := db.GetEngine(ctx).Cols("project_board_id", "sorting").Update(issue); err != nil { + return err + } + } + return nil + }) } diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index 7e26ffbc00..dbface9061 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -471,7 +471,7 @@ func UpdateIssueProject(ctx *context.Context) { } } - if err := issues_model.ChangeProjectAssign(ctx, issue, ctx.Doer, projectID, dstColumnID); err != nil { + if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, projectID, dstColumnID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index 6cd932d76a..efbf8db0dc 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -417,7 +417,7 @@ func UpdateIssueProject(ctx *context.Context) { } } - if err := issues_model.ChangeProjectAssign(ctx, issue, ctx.Doer, projectID, dstColumnID); err != nil { + if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, projectID, dstColumnID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index bdc33acb50..3a06d0f5ea 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1348,7 +1348,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { ctx.ServerError("GetDefaultBoard", err) return } - if err := issues_model.ChangeProjectAssign(ctx, pullIssue, ctx.Doer, projectID, dstDefaultColumn.ID); err != nil { + if err := issues_model.IssueAssignOrRemoveProject(ctx, pullIssue, ctx.Doer, projectID, dstDefaultColumn.ID); err != nil { ctx.ServerError("ChangeProjectAssign", err) return } diff --git a/services/issue/issue.go b/services/issue/issue.go index 6ef4b53c88..7e4048c110 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -50,7 +50,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *issues_mo if err != nil { return err } - if err := issues_model.ChangeProjectAssign(ctx, issue, issue.Poster, projectID, defaultBoard.ID); err != nil { + if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, issue.Poster, projectID, defaultBoard.ID); err != nil { return err } }