Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,8 @@ func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64
"ELSE issue.deadline_unix END DESC")
case "priorityrepo":
sess.OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 ELSE 2 END, issue.created_unix DESC")
case "project-sorting":
sess.Asc("project_issue.sorting")
default:
sess.Desc("issue.created_unix")
}
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ var migrations = []Migration{
NewMigration("Add Branch Protection Unprotected Files Column", addBranchProtectionUnprotectedFilesColumn),
// v195 -> v196
NewMigration("Add table commit_status_index", addTableCommitStatusIndex),
// v196 -> v197
NewMigration("Add Sorting to ProjectIssue table", addProjectIssueSorting),
}

// GetCurrentDBVersion returns the current db version
Expand Down
18 changes: 18 additions & 0 deletions models/migrations/v196.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package migrations

import (
"xorm.io/xorm"
)

func addProjectIssueSorting(x *xorm.Engine) error {
// ProjectIssue saves relation from issue to a project
type ProjectIssue struct {
Sorting int64 `xorm:"NOT NULL DEFAULT 0"`
}

return x.Sync2(new(ProjectIssue))
}
2 changes: 2 additions & 0 deletions models/project_board.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ func (b *ProjectBoard) LoadIssues() (IssueList, error) {
issues, err := Issues(&IssuesOptions{
ProjectBoardID: b.ID,
ProjectID: b.ProjectID,
SortType: "project-sorting",
})
if err != nil {
return nil, err
Expand All @@ -261,6 +262,7 @@ func (b *ProjectBoard) LoadIssues() (IssueList, error) {
issues, err := Issues(&IssuesOptions{
ProjectBoardID: -1, // Issues without ProjectBoardID
ProjectID: b.ProjectID,
SortType: "project-sorting",
})
if err != nil {
return nil, err
Expand Down
8 changes: 5 additions & 3 deletions models/project_issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ProjectIssue struct {

// If 0, then it has not been added to a specific board in the project
ProjectBoardID int64 `xorm:"INDEX"`
Sorting int64 `xorm:"NOT NULL DEFAULT 0"`
}

func init() {
Expand Down Expand Up @@ -182,7 +183,7 @@ func addUpdateIssueProject(e *xorm.Session, issue *Issue, doer *User, newProject
// |__/

// MoveIssueAcrossProjectBoards move a card from one board to another
func MoveIssueAcrossProjectBoards(issue *Issue, board *ProjectBoard) error {
func MoveIssueAcrossProjectBoards(issue *Issue, board *ProjectBoard, sorting int64) error {
sess := db.NewSession(db.DefaultContext)
defer sess.Close()
if err := sess.Begin(); err != nil {
Expand All @@ -200,14 +201,15 @@ func MoveIssueAcrossProjectBoards(issue *Issue, board *ProjectBoard) error {
}

pis.ProjectBoardID = board.ID
if _, err := sess.ID(pis.ID).Cols("project_board_id").Update(&pis); err != nil {
pis.Sorting = sorting
if _, err := sess.ID(pis.ID).Cols("project_board_id").Cols("sorting").Update(&pis); err != nil {
return err
}

return sess.Commit()
}

func (pb *ProjectBoard) removeIssues(e db.Engine) error {
_, err := e.Exec("UPDATE `project_issue` SET project_board_id = 0 WHERE project_board_id = ? ", pb.ID)
_, err := e.Exec("UPDATE `project_issue` SET project_board_id = 0, sorting = 0 WHERE project_board_id = ? ", pb.ID)
return err
}
6 changes: 3 additions & 3 deletions routers/web/repo/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ func ViewProject(ctx *context.Context) {
ctx.ServerError("LoadIssuesOfBoards", err)
return
}
ctx.Data["Issues"] = issueList

linkedPrsMap := make(map[int64][]*models.Issue)
for _, issue := range issueList {
Expand Down Expand Up @@ -587,6 +586,7 @@ func MoveIssueAcrossBoards(ctx *context.Context) {
}

} else {
// column
board, err = models.GetProjectBoard(ctx.ParamsInt64(":boardID"))
if err != nil {
if models.IsErrProjectBoardNotExist(err) {
Expand All @@ -602,7 +602,7 @@ func MoveIssueAcrossBoards(ctx *context.Context) {
}
}

issue, err := models.GetIssueByID(ctx.ParamsInt64(":index"))
issue, err := models.GetIssueByID(ctx.ParamsInt64(":issueIndex"))
if err != nil {
if models.IsErrIssueNotExist(err) {
ctx.NotFound("", nil)
Expand All @@ -613,7 +613,7 @@ func MoveIssueAcrossBoards(ctx *context.Context) {
return
}

if err := models.MoveIssueAcrossProjectBoards(issue, board); err != nil {
if err := models.MoveIssueAcrossProjectBoards(issue, board, ctx.ParamsInt64(":sorting")); err != nil {
ctx.ServerError("MoveIssueAcrossProjectBoards", err)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ func RegisterRoutes(m *web.Route) {
m.Delete("", repo.DeleteProjectBoard)
m.Post("/default", repo.SetDefaultProjectBoard)

m.Post("/{index}", repo.MoveIssueAcrossBoards)
m.Post("/{issueIndex}/{sorting}", repo.MoveIssueAcrossBoards)
})
})
}, reqRepoProjectsWriter, context.RepoMustNotBeArchived())
Expand Down
29 changes: 16 additions & 13 deletions web_src/js/features/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,29 @@ export default async function initProject() {
},
);

const moveIssue = (e) => {
$.ajax(`${e.to.dataset.url}/${e.item.dataset.issue}/${e.newIndex}`, {
headers: {
'X-Csrf-Token': csrf,
'X-Remote': true,
},
contentType: 'application/json',
type: 'POST',
error: () => {
e.from.insertBefore(e.item, e.from.children[e.oldIndex]);
},
});
};

for (const column of boardColumns) {
new Sortable(
column.getElementsByClassName('board')[0],
{
group: 'shared',
animation: 150,
ghostClass: 'card-ghost',
onAdd: (e) => {
$.ajax(`${e.to.dataset.url}/${e.item.dataset.issue}`, {
headers: {
'X-Csrf-Token': csrf,
'X-Remote': true,
},
contentType: 'application/json',
type: 'POST',
error: () => {
e.from.insertBefore(e.item, e.from.children[e.oldIndex]);
},
});
},
onAdd: moveIssue,
onUpdate: moveIssue,
},
);
}
Expand Down