mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Fix project issues list and counting (#33594)
Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
project_model "code.gitea.io/gitea/models/project"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
)
|
||||
|
||||
// MoveIssuesOnProjectColumn moves or keeps issues in a column and sorts them inside that column
|
||||
@@ -84,3 +85,123 @@ func MoveIssuesOnProjectColumn(ctx context.Context, doer *user_model.User, colum
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// LoadIssuesFromProject load issues assigned to each project column inside the given project
|
||||
func LoadIssuesFromProject(ctx context.Context, project *project_model.Project, opts *issues_model.IssuesOptions) (map[int64]issues_model.IssueList, error) {
|
||||
issueList, err := issues_model.Issues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) {
|
||||
o.ProjectID = project.ID
|
||||
o.SortType = "project-column-sorting"
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := issueList.LoadComments(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defaultColumn, err := project.MustDefaultColumn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
issueColumnMap, err := issues_model.LoadProjectIssueColumnMap(ctx, project.ID, defaultColumn.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
results := make(map[int64]issues_model.IssueList)
|
||||
for _, issue := range issueList {
|
||||
projectColumnID, ok := issueColumnMap[issue.ID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := results[projectColumnID]; !ok {
|
||||
results[projectColumnID] = make(issues_model.IssueList, 0)
|
||||
}
|
||||
results[projectColumnID] = append(results[projectColumnID], issue)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// NumClosedIssues return counter of closed issues assigned to a project
|
||||
func loadNumClosedIssues(ctx context.Context, p *project_model.Project) error {
|
||||
cnt, err := db.GetEngine(ctx).Table("project_issue").
|
||||
Join("INNER", "issue", "project_issue.issue_id=issue.id").
|
||||
Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, true).
|
||||
Cols("issue_id").
|
||||
Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.NumClosedIssues = cnt
|
||||
return nil
|
||||
}
|
||||
|
||||
// NumOpenIssues return counter of open issues assigned to a project
|
||||
func loadNumOpenIssues(ctx context.Context, p *project_model.Project) error {
|
||||
cnt, err := db.GetEngine(ctx).Table("project_issue").
|
||||
Join("INNER", "issue", "project_issue.issue_id=issue.id").
|
||||
Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false).
|
||||
Cols("issue_id").
|
||||
Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.NumOpenIssues = cnt
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadIssueNumbersForProjects(ctx context.Context, projects []*project_model.Project, doer *user_model.User) error {
|
||||
for _, project := range projects {
|
||||
if err := LoadIssueNumbersForProject(ctx, project, doer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadIssueNumbersForProject(ctx context.Context, project *project_model.Project, doer *user_model.User) error {
|
||||
// for repository project, just get the numbers
|
||||
if project.OwnerID == 0 {
|
||||
if err := loadNumClosedIssues(ctx, project); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := loadNumOpenIssues(ctx, project); err != nil {
|
||||
return err
|
||||
}
|
||||
project.NumIssues = project.NumClosedIssues + project.NumOpenIssues
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := project.LoadOwner(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// for user or org projects, we need to check access permissions
|
||||
opts := issues_model.IssuesOptions{
|
||||
ProjectID: project.ID,
|
||||
Doer: doer,
|
||||
AllPublic: doer == nil,
|
||||
Owner: project.Owner,
|
||||
}
|
||||
|
||||
var err error
|
||||
project.NumOpenIssues, err = issues_model.CountIssues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) {
|
||||
o.IsClosed = optional.Some(false)
|
||||
}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
project.NumClosedIssues, err = issues_model.CountIssues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) {
|
||||
o.IsClosed = optional.Some(true)
|
||||
}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
project.NumIssues = project.NumClosedIssues + project.NumOpenIssues
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user