Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple assignees #3705

Merged
merged 119 commits into from
May 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
1bd777b
Issue assignees are now loaded of a seperate table when displayed in …
kolaente Mar 3, 2018
3c0b4e1
Multiple assignees work so far, but current state is alpha
kolaente Mar 3, 2018
3d69908
Various cleanups
kolaente Mar 3, 2018
8720925
Made removing all assignees working again
kolaente Mar 5, 2018
edad903
Don't send the action attribute, its not used
kolaente Mar 5, 2018
269f426
Made adding assignes via gui almost work
kolaente Mar 5, 2018
6583569
fmt
kolaente Mar 5, 2018
a0bf332
Made adding assignees work when creating an issue
kolaente Mar 6, 2018
cf6d9d3
cleanup
kolaente Mar 6, 2018
df4dc8d
When viewing issues or prs via the api, assignees are now shown corre…
kolaente Mar 6, 2018
2c88374
Added assignee things when adding/updating an issue/pr via the api
kolaente Mar 7, 2018
8d382ac
Merge remote-tracking branch 'upstream/master' into multiple-assignees
kolaente Mar 11, 2018
fa0f918
Issue assignees now recive notifications
kolaente Mar 11, 2018
8a57bba
Cleanup
kolaente Mar 11, 2018
3f525e0
Added checking for assignees to timetracking
kolaente Mar 11, 2018
0dc735e
Small fixes and improvements
kolaente Mar 11, 2018
f302943
More small fixes and improvements
kolaente Mar 11, 2018
cb9d4d5
Filtering by issue assignee works again
kolaente Mar 11, 2018
4cdfea5
Stats working again when filtering by assignee
kolaente Mar 11, 2018
be8d754
Added old assigneeID when creating an issue/pr
kolaente Mar 11, 2018
fbe62cd
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 13, 2018
2ae1bae
fmt
kolaente Mar 13, 2018
5cddeb5
Fixed assignes showing up two times on issue page
kolaente Mar 13, 2018
e8a019a
fmt + lint
kolaente Mar 13, 2018
d2e780e
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 17, 2018
84540bb
Merge remote-tracking branch 'upstream/master' into multiple-assignees
kolaente Mar 18, 2018
1d9fbc5
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 20, 2018
ed600df
Small design settings
kolaente Mar 20, 2018
660be02
Made adding assignees when creating issues with the api work again
kolaente Mar 20, 2018
55e8e2c
Added editing assignees via api working again
kolaente Mar 20, 2018
423b3f8
fmt
kolaente Mar 20, 2018
b6b18b6
Made pull request assignments via the api work again
kolaente Mar 20, 2018
27acaed
fmt + lint
kolaente Mar 20, 2018
8fd82e6
Last bugfixes + tests work now
kolaente Mar 22, 2018
57cfe61
small improvments + typos
kolaente Mar 22, 2018
26638cd
Merge branch 'master' into multiple-assignees
kolaente Mar 22, 2018
2dea0ee
vendor update
kolaente Mar 22, 2018
e2be76f
Merge remote-tracking branch 'origin/multiple-assignees' into multipl…
kolaente Mar 22, 2018
87a8499
change nothing but trigger ci
kolaente Mar 22, 2018
c06d758
change nothing but trigger ci
kolaente Mar 22, 2018
a6b746b
small improvements and fixes
kolaente Mar 22, 2018
9f9fc22
MakeAssigneeList now uses a pointer to the issue
kolaente Mar 22, 2018
3c38ae2
Added transaction to migration
kolaente Mar 22, 2018
5a5815f
fmt
kolaente Mar 22, 2018
343a932
Added unit tests for multiple assingees + small fixes
kolaente Mar 22, 2018
ee3442e
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 25, 2018
f900090
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 25, 2018
b7600a6
fmt
kolaente Mar 25, 2018
04ed047
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 25, 2018
b3bdd85
Merge branch 'master' into multiple-assignees
jonasfranz Mar 25, 2018
c42a9b4
Merge remote-tracking branch 'origin/multiple-assignees' into multipl…
kolaente Mar 25, 2018
44bd7a5
Improvments to removing already existing issue assignees via the api
kolaente Mar 25, 2018
19bba7c
fixed lint
kolaente Mar 25, 2018
e89bf78
Added descriptive comment
kolaente Mar 25, 2018
194ba16
Change nothing but TRIGGER THE FUCKING CI SO IT PICKS UP THE LATEST C…
kolaente Mar 25, 2018
d1d5316
Change nothing but TRIGGER THE FUCKING CI SO IT PICKS UP THE LATEST C…
kolaente Mar 25, 2018
494ee08
fmt
kolaente Mar 25, 2018
16c609a
Change nothing but TRIGGER THE FUCKING CI SO IT PICKS UP THE LATEST C…
kolaente Mar 25, 2018
2303fc0
Change nothing but TRIGGER THE FUCKING CI SO IT PICKS UP THE LATEST C…
kolaente Mar 25, 2018
3d8e037
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 28, 2018
d47c230
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Mar 28, 2018
07b3e10
Small fixes and improvments
kolaente Mar 28, 2018
c9bd49a
Deleted unnessecary license headers
kolaente Mar 28, 2018
d3b3a4c
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 3, 2018
8d33ef8
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 3, 2018
a95dad3
Added custom error type if a passed user does not has access to the r…
kolaente Apr 4, 2018
066eef4
Added custom error type if a passed user does not has access to the r…
kolaente Apr 4, 2018
2f4b6f8
Improved loading assignees for a list of issues
kolaente Apr 4, 2018
9f9f435
Improved adding/removing assignees via UI
kolaente Apr 4, 2018
3d12ded
Improved adding/removing assignees via UI
kolaente Apr 4, 2018
91aa3de
cleanup
kolaente Apr 10, 2018
bed774c
Merge branch 'master' into multiple-assignees
kolaente Apr 10, 2018
84dd68f
Merge branch 'master' into multiple-assignees
kolaente Apr 11, 2018
7014d05
Merge branch 'master' into multiple-assignees
kolaente Apr 13, 2018
248d252
(hopefully) fixed postgresql error when building issue list with assi…
kolaente Apr 14, 2018
6075a1e
Merge remote-tracking branch 'origin/multiple-assignees' into multipl…
kolaente Apr 14, 2018
0bfbeef
(hopefully) fixed postgresql error when building issue list with assi…
kolaente Apr 14, 2018
71e9ebc
Fixed assignee select dropdown ui
kolaente Apr 15, 2018
3a49f58
Simplified loading assignees for one issue
kolaente Apr 15, 2018
893565e
fixed import order
kolaente Apr 15, 2018
e2292ff
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 16, 2018
7eb284a
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 16, 2018
e121931
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 18, 2018
461a594
Added cleanup to migration
kolaente Apr 20, 2018
b55e8b5
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 20, 2018
139724d
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 21, 2018
0518f20
Added dropping is_assigned from issue_user in migration
kolaente Apr 21, 2018
a0919ff
Modified migration to use xorm session instead of xorm engine
kolaente Apr 23, 2018
f9cb8a1
Modified migration to use xorm session instead of xorm engine
kolaente Apr 23, 2018
bdda006
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 23, 2018
3181f53
Added xorm session transaction
kolaente Apr 26, 2018
e79b5d4
removed unecessary join
kolaente Apr 26, 2018
b5d65cb
small improvements to issue list with assignees
kolaente Apr 26, 2018
8e0395a
Error handling in the migration
kolaente Apr 27, 2018
97e7ed9
Merge branch 'master' into multiple-assignees
lunny Apr 29, 2018
c3db90a
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 29, 2018
cc38f07
fmt
kolaente Apr 29, 2018
5f692ec
Merge remote-tracking branch 'origin/multiple-assignees' into multipl…
kolaente Apr 29, 2018
0102751
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente Apr 29, 2018
aea7776
Merge with gitea-master
kolaente May 1, 2018
48c9acf
Merge with gitea-master
kolaente May 1, 2018
137b952
Updated gitea-sdk
kolaente May 1, 2018
aedf5d1
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 1, 2018
b54e0b6
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 1, 2018
e6562ff
updated stylesheets
kolaente May 1, 2018
4767b09
updated swagger.json
kolaente May 1, 2018
cbf9c5d
Simplified clearing all assignees
kolaente May 2, 2018
259cb5f
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 2, 2018
4f8aa91
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 2, 2018
c7d14bc
Fixed undefined "Assignee" in issues list
kolaente May 4, 2018
0a7ff44
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 5, 2018
aa11367
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 5, 2018
a0d8cde
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 6, 2018
4b31e99
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 6, 2018
bbf1320
Merge branch 'master' into multiple-assignees
lunny May 9, 2018
fade599
Fixed page reload when clearing all assignees in new issue form
kolaente May 9, 2018
323c9b3
Merge branch 'master' into multiple-assignees
lunny May 9, 2018
a1f6fa9
Merge branch 'master' of https://github.com/go-gitea/gitea into multi…
kolaente May 9, 2018
f87edc7
Merge remote-tracking branch 'origin/multiple-assignees' into multipl…
kolaente May 9, 2018
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
16 changes: 16 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,22 @@ func (err ErrRepoFileAlreadyExist) Error() string {
return fmt.Sprintf("repository file already exists [file_name: %s]", err.FileName)
}

// ErrUserDoesNotHaveAccessToRepo represets an error where the user doesn't has access to a given repo
type ErrUserDoesNotHaveAccessToRepo struct {
UserID int64
RepoName string
}

// IsErrUserDoesNotHaveAccessToRepo checks if an error is a ErrRepoFileAlreadyExist.
func IsErrUserDoesNotHaveAccessToRepo(err error) bool {
_, ok := err.(ErrUserDoesNotHaveAccessToRepo)
return ok
}

func (err ErrUserDoesNotHaveAccessToRepo) Error() string {
return fmt.Sprintf("user doesn't have acces to repo [user_id: %d, repo_name: %s]", err.UserID, err.RepoName)
}

// __________ .__
// \______ \____________ ____ ____ | |__
// | | _/\_ __ \__ \ / \_/ ___\| | \
Expand Down
2 changes: 0 additions & 2 deletions models/fixtures/issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
repo_id: 1
index: 1
poster_id: 1
assignee_id: 1
name: issue1
content: content for the first issue
is_closed: false
Expand Down Expand Up @@ -67,7 +66,6 @@
repo_id: 3
index: 1
poster_id: 1
assignee_id: 1
name: issue6
content: content6
is_closed: false
Expand Down
8 changes: 8 additions & 0 deletions models/fixtures/issue_assignees.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-
id: 1
assignee_id: 1
issue_id: 1
-
id: 2
assignee_id: 1
issue_id: 6
3 changes: 0 additions & 3 deletions models/fixtures/issue_user.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@
uid: 1
issue_id: 1
is_read: true
is_assigned: true
is_mentioned: false

-
id: 2
uid: 2
issue_id: 1
is_read: true
is_assigned: false
is_mentioned: false

-
id: 3
uid: 4
issue_id: 1
is_read: false
is_assigned: false
is_mentioned: false
159 changes: 57 additions & 102 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Issue struct {
MilestoneID int64 `xorm:"INDEX"`
Milestone *Milestone `xorm:"-"`
Priority int
AssigneeID int64 `xorm:"INDEX"`
AssigneeID int64 `xorm:"-"`
Assignee *User `xorm:"-"`
IsClosed bool `xorm:"INDEX"`
IsRead bool `xorm:"-"`
Expand All @@ -56,6 +56,7 @@ type Issue struct {
Comments []*Comment `xorm:"-"`
Reactions ReactionList `xorm:"-"`
TotalTrackedTime int64 `xorm:"-"`
Assignees []*User `xorm:"-"`
}

var (
Expand Down Expand Up @@ -140,22 +141,6 @@ func (issue *Issue) loadPoster(e Engine) (err error) {
return
}

func (issue *Issue) loadAssignee(e Engine) (err error) {
if issue.Assignee == nil && issue.AssigneeID > 0 {
issue.Assignee, err = getUserByID(e, issue.AssigneeID)
if err != nil {
issue.AssigneeID = -1
issue.Assignee = NewGhostUser()
if !IsErrUserNotExist(err) {
return fmt.Errorf("getUserByID.(assignee) [%d]: %v", issue.AssigneeID, err)
}
err = nil
return
}
}
return
}

func (issue *Issue) loadPullRequest(e Engine) (err error) {
if issue.IsPull && issue.PullRequest == nil {
issue.PullRequest, err = getPullRequestByIssueID(e, issue.ID)
Expand Down Expand Up @@ -231,7 +216,7 @@ func (issue *Issue) loadAttributes(e Engine) (err error) {
}
}

if err = issue.loadAssignee(e); err != nil {
if err = issue.loadAssignees(e); err != nil {
return
}

Expand Down Expand Up @@ -343,8 +328,11 @@ func (issue *Issue) APIFormat() *api.Issue {
if issue.Milestone != nil {
apiIssue.Milestone = issue.Milestone.APIFormat()
}
if issue.Assignee != nil {
apiIssue.Assignee = issue.Assignee.APIFormat()
if len(issue.Assignees) > 0 {
for _, assignee := range issue.Assignees {
apiIssue.Assignees = append(apiIssue.Assignees, assignee.APIFormat())
}
apiIssue.Assignee = issue.Assignees[0].APIFormat() // For compatibility, we're keeping the first assignee as `apiIssue.Assignee`
}
if issue.IsPull {
apiIssue.PullRequest = &api.PullRequestMeta{
Expand Down Expand Up @@ -605,19 +593,6 @@ func (issue *Issue) ReplaceLabels(labels []*Label, doer *User) (err error) {
return sess.Commit()
}

// GetAssignee sets the Assignee attribute of this issue.
func (issue *Issue) GetAssignee() (err error) {
if issue.AssigneeID == 0 || issue.Assignee != nil {
return nil
}

issue.Assignee, err = GetUserByID(issue.AssigneeID)
if IsErrUserNotExist(err) {
return nil
}
return err
}

// ReadBy sets issue to be read by given user.
func (issue *Issue) ReadBy(userID int64) error {
if err := UpdateIssueUserByRead(userID, issue.ID); err != nil {
Expand Down Expand Up @@ -823,55 +798,6 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
return nil
}

// ChangeAssignee changes the Assignee field of this issue.
func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
var oldAssigneeID = issue.AssigneeID
issue.AssigneeID = assigneeID
if err = UpdateIssueUserByAssignee(issue); err != nil {
return fmt.Errorf("UpdateIssueUserByAssignee: %v", err)
}

sess := x.NewSession()
defer sess.Close()

if err = issue.loadRepo(sess); err != nil {
return fmt.Errorf("loadRepo: %v", err)
}

if _, err = createAssigneeComment(sess, doer, issue.Repo, issue, oldAssigneeID, assigneeID); err != nil {
return fmt.Errorf("createAssigneeComment: %v", err)
}

issue.Assignee, err = GetUserByID(issue.AssigneeID)
if err != nil && !IsErrUserNotExist(err) {
log.Error(4, "GetUserByID [assignee_id: %v]: %v", issue.AssigneeID, err)
return nil
}

// Error not nil here means user does not exist, which is remove assignee.
isRemoveAssignee := err != nil
if issue.IsPull {
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormat(AccessModeNone),
Sender: doer.APIFormat(),
}
if isRemoveAssignee {
apiPullRequest.Action = api.HookIssueUnassigned
} else {
apiPullRequest.Action = api.HookIssueAssigned
}
if err := PrepareWebhooks(issue.Repo, HookEventPullRequest, apiPullRequest); err != nil {
log.Error(4, "PrepareWebhooks [is_pull: %v, remove_assignee: %v]: %v", issue.IsPull, isRemoveAssignee, err)
return nil
}
}
go HookQueue.Add(issue.RepoID)
return nil
}

// GetTasks returns the amount of tasks in the issues content
func (issue *Issue) GetTasks() int {
return len(issueTasksPat.FindAllStringIndex(issue.Content, -1))
Expand All @@ -887,6 +813,7 @@ type NewIssueOptions struct {
Repo *Repository
Issue *Issue
LabelIDs []int64
AssigneeIDs []int64
Attachments []string // In UUID format.
IsPull bool
}
Expand All @@ -909,14 +836,32 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
}
}

if assigneeID := opts.Issue.AssigneeID; assigneeID > 0 {
valid, err := hasAccess(e, assigneeID, opts.Repo, AccessModeWrite)
if err != nil {
return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", assigneeID, opts.Repo.ID, err)
// Keep the old assignee id thingy for compatibility reasons
if opts.Issue.AssigneeID > 0 {
isAdded := false
// Check if the user has already been passed to issue.AssigneeIDs, if not, add it
for _, aID := range opts.AssigneeIDs {
if aID == opts.Issue.AssigneeID {
isAdded = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could break here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

break
}
}
if !valid {
opts.Issue.AssigneeID = 0
opts.Issue.Assignee = nil

if !isAdded {
opts.AssigneeIDs = append(opts.AssigneeIDs, opts.Issue.AssigneeID)
}
}

// Check for and validate assignees
if len(opts.AssigneeIDs) > 0 {
for _, assigneeID := range opts.AssigneeIDs {
valid, err := hasAccess(e, assigneeID, opts.Repo, AccessModeWrite)
if err != nil {
return fmt.Errorf("hasAccess [user_id: %d, repo_id: %d]: %v", assigneeID, opts.Repo.ID, err)
}
if !valid {
return ErrUserDoesNotHaveAccessToRepo{UserID: assigneeID, RepoName: opts.Repo.Name}
}
}
}

Expand All @@ -931,11 +876,10 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
}
}

if opts.Issue.AssigneeID > 0 {
if err = opts.Issue.loadRepo(e); err != nil {
return err
}
if _, err = createAssigneeComment(e, doer, opts.Issue.Repo, opts.Issue, -1, opts.Issue.AssigneeID); err != nil {
// Insert the assignees
for _, assigneeID := range opts.AssigneeIDs {
err = opts.Issue.changeAssignee(e, doer, assigneeID)
if err != nil {
return err
}
}
Expand Down Expand Up @@ -995,7 +939,7 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
}

// NewIssue creates new issue with labels for repository.
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, assigneeIDs []int64, uuids []string) (err error) {
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
Expand All @@ -1007,7 +951,11 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
Issue: issue,
LabelIDs: labelIDs,
Attachments: uuids,
AssigneeIDs: assigneeIDs,
}); err != nil {
if IsErrUserDoesNotHaveAccessToRepo(err) {
return err
}
return fmt.Errorf("newIssue: %v", err)
}

Expand Down Expand Up @@ -1150,7 +1098,8 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) error {
}

if opts.AssigneeID > 0 {
sess.And("issue.assignee_id=?", opts.AssigneeID)
sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", opts.AssigneeID)
}

if opts.PosterID > 0 {
Expand Down Expand Up @@ -1372,7 +1321,8 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
}

if opts.AssigneeID > 0 {
sess.And("issue.assignee_id = ?", opts.AssigneeID)
sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", opts.AssigneeID)
}

if opts.PosterID > 0 {
Expand Down Expand Up @@ -1438,13 +1388,15 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
}
case FilterModeAssign:
stats.OpenCount, err = x.Where(cond).And("is_closed = ?", false).
And("assignee_id = ?", opts.UserID).
Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", opts.UserID).
Count(new(Issue))
if err != nil {
return nil, err
}
stats.ClosedCount, err = x.Where(cond).And("is_closed = ?", true).
And("assignee_id = ?", opts.UserID).
Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", opts.UserID).
Count(new(Issue))
if err != nil {
return nil, err
Expand All @@ -1466,7 +1418,8 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {

cond = cond.And(builder.Eq{"issue.is_closed": opts.IsClosed})
stats.AssignCount, err = x.Where(cond).
And("assignee_id = ?", opts.UserID).
Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", opts.UserID).
Count(new(Issue))
if err != nil {
return nil, err
Expand Down Expand Up @@ -1505,8 +1458,10 @@ func GetRepoIssueStats(repoID, uid int64, filterMode int, isPull bool) (numOpen

switch filterMode {
case FilterModeAssign:
openCountSession.And("assignee_id = ?", uid)
closedCountSession.And("assignee_id = ?", uid)
openCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", uid)
closedCountSession.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", uid)
case FilterModeCreate:
openCountSession.And("poster_id = ?", uid)
closedCountSession.And("poster_id = ?", uid)
Expand Down
Loading