fix: adapt to upstream refactor, fix IssueAssignOrRemoveProject signature and column move logic
This commit is contained in:
@@ -95,3 +95,20 @@ func DeleteAllProjectIssueByIssueIDsAndProjectIDs(ctx context.Context, issueIDs,
|
|||||||
_, err := db.GetEngine(ctx).In("project_id", projectIDs).In("issue_id", issueIDs).Delete(&ProjectIssue{})
|
_, err := db.GetEngine(ctx).In("project_id", projectIDs).In("issue_id", issueIDs).Delete(&ProjectIssue{})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MoveIssueToColumn moves a single issue to a specific column within a project.
|
||||||
|
func MoveIssueToColumn(ctx context.Context, issueID, projectID, columnID int64) error {
|
||||||
|
nextSorting, err := GetColumnIssueNextSorting(ctx, projectID, columnID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = db.GetEngine(ctx).
|
||||||
|
Where("issue_id=? AND project_id=?", issueID, projectID).
|
||||||
|
Cols("project_board_id", "sorting").
|
||||||
|
Update(&ProjectIssue{
|
||||||
|
ProjectColumnID: columnID,
|
||||||
|
Sorting: nextSorting,
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -836,11 +836,15 @@ func assignIssueToProjectColumn(ctx *context.APIContext, add bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
projectID := column.ProjectID
|
if err := issue.LoadProjects(ctx); err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentProjectIDs := make([]int64, 0, len(issue.Projects))
|
||||||
|
for _, p := range issue.Projects {
|
||||||
|
currentProjectIDs = append(currentProjectIDs, p.ID)
|
||||||
|
}
|
||||||
if !add {
|
if !add {
|
||||||
// Confirm the issue is currently in this specific column before removing,
|
|
||||||
// since IssueAssignOrRemoveProject(projectID=0) clears the issue's project
|
|
||||||
// assignment unconditionally.
|
|
||||||
exists, err := project_model.IsIssueInColumn(ctx, issue.ID, column.ProjectID, column.ID)
|
exists, err := project_model.IsIssueInColumn(ctx, issue.ID, column.ProjectID, column.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.APIErrorInternal(err)
|
ctx.APIErrorInternal(err)
|
||||||
@@ -850,11 +854,38 @@ func assignIssueToProjectColumn(ctx *context.APIContext, add bool) {
|
|||||||
ctx.APIErrorNotFound()
|
ctx.APIErrorNotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
projectID = 0
|
newProjectIDs := make([]int64, 0, len(currentProjectIDs))
|
||||||
}
|
for _, id := range currentProjectIDs {
|
||||||
if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, []int64{projectID}); err != nil {
|
if id != column.ProjectID {
|
||||||
ctx.APIErrorInternal(err)
|
newProjectIDs = append(newProjectIDs, id)
|
||||||
return
|
}
|
||||||
|
}
|
||||||
|
if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, newProjectIDs); err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Check if issue is already in this project
|
||||||
|
alreadyInProject := false
|
||||||
|
for _, id := range currentProjectIDs {
|
||||||
|
if id == column.ProjectID {
|
||||||
|
alreadyInProject = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !alreadyInProject {
|
||||||
|
// Add to project first (lands in default column)
|
||||||
|
newProjectIDs := append(currentProjectIDs, column.ProjectID)
|
||||||
|
if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, newProjectIDs); err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Move to target column
|
||||||
|
if err := project_model.MoveIssueToColumn(ctx, issue.ID, column.ProjectID, column.ID); err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if add {
|
if add {
|
||||||
|
|||||||
@@ -563,9 +563,9 @@ func testAPIListProjectColumnIssues(t *testing.T) {
|
|||||||
err = project_model.NewColumn(t.Context(), column)
|
err = project_model.NewColumn(t.Context(), column)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = issues_model.IssueAssignOrRemoveProject(t.Context(), issue, owner, project.ID, column.ID)
|
err = issues_model.IssueAssignOrRemoveProject(t.Context(), issue, owner, []int64{project.ID})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = issues_model.IssueAssignOrRemoveProject(t.Context(), pull, owner, project.ID, column.ID)
|
err = issues_model.IssueAssignOrRemoveProject(t.Context(), pull, owner, []int64{project.ID})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeReadIssue)
|
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeReadIssue)
|
||||||
@@ -617,7 +617,7 @@ func testAPIRemoveIssueFromProjectColumn(t *testing.T) {
|
|||||||
err = project_model.NewColumn(t.Context(), otherColumn)
|
err = project_model.NewColumn(t.Context(), otherColumn)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = issues_model.IssueAssignOrRemoveProject(t.Context(), issue, owner, project.ID, column.ID)
|
err = issues_model.IssueAssignOrRemoveProject(t.Context(), issue, owner, []int64{project.ID})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
|
token := getUserToken(t, owner.Name, auth_model.AccessTokenScopeWriteIssue)
|
||||||
|
|||||||
@@ -298,11 +298,10 @@ func TestOrgProjectFilterByMilestone(t *testing.T) {
|
|||||||
columns, err := project_model.GetProjectColumns(t.Context(), project.ID, db.ListOptionsAll)
|
columns, err := project_model.GetProjectColumns(t.Context(), project.ID, db.ListOptionsAll)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, columns)
|
require.NotEmpty(t, columns)
|
||||||
defaultColumnID := columns[0].ID
|
|
||||||
|
|
||||||
// Add issues to the project
|
// Add issues to the project
|
||||||
require.NoError(t, issues_model.IssueAssignOrRemoveProject(t.Context(), issue16, user1, project.ID, defaultColumnID))
|
require.NoError(t, issues_model.IssueAssignOrRemoveProject(t.Context(), issue16, user1, []int64{project.ID}))
|
||||||
require.NoError(t, issues_model.IssueAssignOrRemoveProject(t.Context(), issue17, user1, project.ID, defaultColumnID))
|
require.NoError(t, issues_model.IssueAssignOrRemoveProject(t.Context(), issue17, user1, []int64{project.ID}))
|
||||||
|
|
||||||
sess := loginUser(t, "user1")
|
sess := loginUser(t, "user1")
|
||||||
projectURL := fmt.Sprintf("/org3/-/projects/%d", project.ID)
|
projectURL := fmt.Sprintf("/org3/-/projects/%d", project.ID)
|
||||||
|
|||||||
Reference in New Issue
Block a user