|
|
@ -10,14 +10,15 @@ import ( |
|
|
|
"sort" |
|
|
|
"sort" |
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
|
|
api "code.gitea.io/sdk/gitea" |
|
|
|
|
|
|
|
"github.com/Unknwon/com" |
|
|
|
|
|
|
|
"github.com/go-xorm/xorm" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"code.gitea.io/gitea/modules/base" |
|
|
|
"code.gitea.io/gitea/modules/base" |
|
|
|
"code.gitea.io/gitea/modules/log" |
|
|
|
"code.gitea.io/gitea/modules/log" |
|
|
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
"code.gitea.io/gitea/modules/setting" |
|
|
|
"code.gitea.io/gitea/modules/util" |
|
|
|
"code.gitea.io/gitea/modules/util" |
|
|
|
|
|
|
|
api "code.gitea.io/sdk/gitea" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/Unknwon/com" |
|
|
|
|
|
|
|
"github.com/go-xorm/builder" |
|
|
|
|
|
|
|
"github.com/go-xorm/xorm" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// Issue represents an issue or pull request of repository.
|
|
|
|
// Issue represents an issue or pull request of repository.
|
|
|
@ -1022,12 +1023,11 @@ func GetIssuesByIDs(issueIDs []int64) ([]*Issue, error) { |
|
|
|
|
|
|
|
|
|
|
|
// IssuesOptions represents options of an issue.
|
|
|
|
// IssuesOptions represents options of an issue.
|
|
|
|
type IssuesOptions struct { |
|
|
|
type IssuesOptions struct { |
|
|
|
RepoID int64 |
|
|
|
RepoIDs []int64 // include all repos if empty
|
|
|
|
AssigneeID int64 |
|
|
|
AssigneeID int64 |
|
|
|
PosterID int64 |
|
|
|
PosterID int64 |
|
|
|
MentionedID int64 |
|
|
|
MentionedID int64 |
|
|
|
MilestoneID int64 |
|
|
|
MilestoneID int64 |
|
|
|
RepoIDs []int64 |
|
|
|
|
|
|
|
Page int |
|
|
|
Page int |
|
|
|
PageSize int |
|
|
|
PageSize int |
|
|
|
IsClosed util.OptionalBool |
|
|
|
IsClosed util.OptionalBool |
|
|
@ -1073,9 +1073,7 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) error { |
|
|
|
sess.In("issue.id", opts.IssueIDs) |
|
|
|
sess.In("issue.id", opts.IssueIDs) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if opts.RepoID > 0 { |
|
|
|
if len(opts.RepoIDs) > 0 { |
|
|
|
sess.And("issue.repo_id=?", opts.RepoID) |
|
|
|
|
|
|
|
} else if len(opts.RepoIDs) > 0 { |
|
|
|
|
|
|
|
// In case repository IDs are provided but actually no repository has issue.
|
|
|
|
// In case repository IDs are provided but actually no repository has issue.
|
|
|
|
sess.In("issue.repo_id", opts.RepoIDs) |
|
|
|
sess.In("issue.repo_id", opts.RepoIDs) |
|
|
|
} |
|
|
|
} |
|
|
@ -1339,58 +1337,92 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) { |
|
|
|
return stats, err |
|
|
|
return stats, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// UserIssueStatsOptions contains parameters accepted by GetUserIssueStats.
|
|
|
|
|
|
|
|
type UserIssueStatsOptions struct { |
|
|
|
|
|
|
|
UserID int64 |
|
|
|
|
|
|
|
RepoID int64 |
|
|
|
|
|
|
|
UserRepoIDs []int64 |
|
|
|
|
|
|
|
FilterMode int |
|
|
|
|
|
|
|
IsPull bool |
|
|
|
|
|
|
|
IsClosed bool |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetUserIssueStats returns issue statistic information for dashboard by given conditions.
|
|
|
|
// GetUserIssueStats returns issue statistic information for dashboard by given conditions.
|
|
|
|
func GetUserIssueStats(repoID, uid int64, repoIDs []int64, filterMode int, isPull bool) *IssueStats { |
|
|
|
func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) { |
|
|
|
|
|
|
|
var err error |
|
|
|
stats := &IssueStats{} |
|
|
|
stats := &IssueStats{} |
|
|
|
|
|
|
|
|
|
|
|
countSession := func(isClosed, isPull bool, repoID int64, repoIDs []int64) *xorm.Session { |
|
|
|
cond := builder.NewCond() |
|
|
|
sess := x. |
|
|
|
cond = cond.And(builder.Eq{"issue.is_pull": opts.IsPull}) |
|
|
|
Where("issue.is_closed = ?", isClosed). |
|
|
|
if opts.RepoID > 0 { |
|
|
|
And("issue.is_pull = ?", isPull) |
|
|
|
cond = cond.And(builder.Eq{"issue.repo_id": opts.RepoID}) |
|
|
|
|
|
|
|
|
|
|
|
if repoID > 0 { |
|
|
|
|
|
|
|
sess.And("repo_id = ?", repoID) |
|
|
|
|
|
|
|
} else if len(repoIDs) > 0 { |
|
|
|
|
|
|
|
sess.In("repo_id", repoIDs) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return sess |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
stats.AssignCount, _ = countSession(false, isPull, repoID, nil). |
|
|
|
switch opts.FilterMode { |
|
|
|
And("assignee_id = ?", uid). |
|
|
|
|
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stats.CreateCount, _ = countSession(false, isPull, repoID, nil). |
|
|
|
|
|
|
|
And("poster_id = ?", uid). |
|
|
|
|
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stats.YourRepositoriesCount, _ = countSession(false, isPull, repoID, repoIDs). |
|
|
|
|
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch filterMode { |
|
|
|
|
|
|
|
case FilterModeAll: |
|
|
|
case FilterModeAll: |
|
|
|
stats.OpenCount, _ = countSession(false, isPull, repoID, repoIDs). |
|
|
|
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false). |
|
|
|
|
|
|
|
And(builder.In("issue.repo_id", opts.UserRepoIDs)). |
|
|
|
Count(new(Issue)) |
|
|
|
Count(new(Issue)) |
|
|
|
stats.ClosedCount, _ = countSession(true, isPull, repoID, repoIDs). |
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true). |
|
|
|
|
|
|
|
And(builder.In("issue.repo_id", opts.UserRepoIDs)). |
|
|
|
Count(new(Issue)) |
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
case FilterModeAssign: |
|
|
|
case FilterModeAssign: |
|
|
|
stats.OpenCount, _ = countSession(false, isPull, repoID, nil). |
|
|
|
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false). |
|
|
|
And("assignee_id = ?", uid). |
|
|
|
And("assignee_id = ?", opts.UserID). |
|
|
|
Count(new(Issue)) |
|
|
|
Count(new(Issue)) |
|
|
|
stats.ClosedCount, _ = countSession(true, isPull, repoID, nil). |
|
|
|
if err != nil { |
|
|
|
And("assignee_id = ?", uid). |
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true). |
|
|
|
|
|
|
|
And("assignee_id = ?", opts.UserID). |
|
|
|
Count(new(Issue)) |
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
case FilterModeCreate: |
|
|
|
case FilterModeCreate: |
|
|
|
stats.OpenCount, _ = countSession(false, isPull, repoID, nil). |
|
|
|
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false). |
|
|
|
And("poster_id = ?", uid). |
|
|
|
And("poster_id = ?", opts.UserID). |
|
|
|
|
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true). |
|
|
|
|
|
|
|
And("poster_id = ?", opts.UserID). |
|
|
|
|
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cond = cond.And(builder.Eq{"issue.is_closed": opts.IsClosed}) |
|
|
|
|
|
|
|
stats.AssignCount, err = x.Where(cond). |
|
|
|
|
|
|
|
And("assignee_id = ?", opts.UserID). |
|
|
|
Count(new(Issue)) |
|
|
|
Count(new(Issue)) |
|
|
|
stats.ClosedCount, _ = countSession(true, isPull, repoID, nil). |
|
|
|
if err != nil { |
|
|
|
And("poster_id = ?", uid). |
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stats.CreateCount, err = x.Where(cond). |
|
|
|
|
|
|
|
And("poster_id = ?", opts.UserID). |
|
|
|
Count(new(Issue)) |
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stats.YourRepositoriesCount, err = x.Where(cond). |
|
|
|
|
|
|
|
And(builder.In("issue.repo_id", opts.UserRepoIDs)). |
|
|
|
|
|
|
|
Count(new(Issue)) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return stats |
|
|
|
return stats, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
|
|
|
|
// GetRepoIssueStats returns number of open and closed repository issues by given filter mode.
|
|
|
|