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

Add ability to see open and closed issues at the same time #28757

Merged
merged 2 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 7 additions & 5 deletions models/issues/tracked_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ func GetTrackedTimeByID(ctx context.Context, id int64) (*TrackedTime, error) {
}

// GetIssueTotalTrackedTime returns the total tracked time for issues by given conditions.
func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed bool) (int64, error) {
func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed util.OptionalBool) (int64, error) {
if len(opts.IssueIDs) <= MaxQueryParameters {
return getIssueTotalTrackedTimeChunk(ctx, opts, isClosed, opts.IssueIDs)
}
Expand All @@ -363,7 +363,7 @@ func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed
return accum, nil
}

func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isClosed bool, issueIDs []int64) (int64, error) {
func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isClosed util.OptionalBool, issueIDs []int64) (int64, error) {
sumSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session {
sess := db.GetEngine(ctx).
Table("tracked_time").
Expand All @@ -377,7 +377,9 @@ func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isC
Time int64
}

return sumSession(opts, issueIDs).
And("issue.is_closed = ?", isClosed).
SumInt(new(trackedTime), "tracked_time.time")
session := sumSession(opts, issueIDs)
if !isClosed.IsNone() {
session = session.And("issue.is_closed = ?", isClosed.IsTrue())
}
return session.SumInt(new(trackedTime), "tracked_time.time")
}
9 changes: 7 additions & 2 deletions models/issues/tracked_time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/util"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -119,11 +120,15 @@ func TestTotalTimesForEachUser(t *testing.T) {
func TestGetIssueTotalTrackedTime(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, false)
ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolFalse)
assert.NoError(t, err)
assert.EqualValues(t, 3682, ttt)

ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, true)
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolTrue)
assert.NoError(t, err)
assert.EqualValues(t, 0, ttt)

ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolNone)
assert.NoError(t, err)
assert.EqualValues(t, 3682, ttt)
}
36 changes: 26 additions & 10 deletions routers/web/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,18 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
}
}

isShowClosed := ctx.FormString("state") == "closed"
// if open issues are zero and close don't, use closed as default
var isShowClosed util.OptionalBool
switch ctx.FormString("state") {
case "closed":
isShowClosed = util.OptionalBoolTrue
case "all":
isShowClosed = util.OptionalBoolNone
default:
isShowClosed = util.OptionalBoolFalse
}
// if there are closed issues and no open issues, default to showing all issues
if len(ctx.FormString("state")) == 0 && issueStats.OpenCount == 0 && issueStats.ClosedCount != 0 {
isShowClosed = true
isShowClosed = util.OptionalBoolNone
}

if repo.IsTimetrackerEnabled(ctx) {
Expand All @@ -260,10 +268,13 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
}

var total int
if !isShowClosed {
total = int(issueStats.OpenCount)
} else {
switch isShowClosed {
case util.OptionalBoolTrue:
total = int(issueStats.ClosedCount)
case util.OptionalBoolNone:
total = int(issueStats.OpenCount + issueStats.ClosedCount)
default:
total = int(issueStats.OpenCount)
}
pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, 5)

Expand All @@ -282,7 +293,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
ReviewedID: reviewedID,
MilestoneIDs: mileIDs,
ProjectID: projectID,
IsClosed: util.OptionalBoolOf(isShowClosed),
IsClosed: isShowClosed,
IsPull: isPullOption,
LabelIDs: labelIDs,
SortType: sortType,
Expand Down Expand Up @@ -428,6 +439,9 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
ctx.Data["OpenCount"] = issueStats.OpenCount
ctx.Data["ClosedCount"] = issueStats.ClosedCount
linkStr := "%s?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&archived=%t"
ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr, ctx.Link,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "all", url.QueryEscape(selectLabels),
mentionedID, projectID, assigneeID, posterID, archived)
ctx.Data["OpenLink"] = fmt.Sprintf(linkStr, ctx.Link,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "open", url.QueryEscape(selectLabels),
mentionedID, projectID, assigneeID, posterID, archived)
Expand All @@ -442,11 +456,13 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
ctx.Data["ProjectID"] = projectID
ctx.Data["AssigneeID"] = assigneeID
ctx.Data["PosterID"] = posterID
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["Keyword"] = keyword
if isShowClosed {
switch isShowClosed {
case util.OptionalBoolTrue:
ctx.Data["State"] = "closed"
} else {
case util.OptionalBoolNone:
ctx.Data["State"] = "all"
default:
ctx.Data["State"] = "open"
}
ctx.Data["ShowArchivedLabels"] = archived
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/issue/openclose.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="small-menu-items ui compact tiny menu">
<a class="{{if not .IsShowClosed}}active {{end}}item" href="{{.OpenLink}}">
<a class="{{if eq .State "open"}}active {{end}}item" href="{{if eq .State "open"}}{{.AllStatesLink}}{{else}}{{.OpenLink}}{{end}}">
{{if .PageIsMilestones}}
{{svg "octicon-milestone" 16 "gt-mr-3"}}
{{else if .PageIsPullList}}
Expand All @@ -9,7 +9,7 @@
{{end}}
{{ctx.Locale.PrettyNumber .OpenCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.open_title"}}
</a>
<a class="{{if .IsShowClosed}}active {{end}}item" href="{{.ClosedLink}}">
<a class="{{if eq .State "closed"}}active {{end}}item" href="{{if eq .State "closed"}}{{.AllStatesLink}}{{else}}{{.ClosedLink}}{{end}}">
{{svg "octicon-check" 16 "gt-mr-3"}}
{{ctx.Locale.PrettyNumber .ClosedCount}}&nbsp;{{ctx.Locale.Tr "repo.issues.closed_title"}}
</a>
Expand Down