mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-05 23:46:43 +00:00
fix(label): sort labels by open issue count, not total (#39464)
The labels page shows open issue counts, but "Most issues" and "Least issues" sorted by the total including closed issues, so a label with no open issues could land in the middle of the list. - Sort repository and organization labels by their open issue count - Sort organization labels on a repository's labels page by their open issues in that repository, which is the count they display Fixes: https://github.com/go-gitea/gitea/issues/39346 --------- Signed-off-by: piyush295 <mr.piyush295@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
@@ -433,12 +433,13 @@ func GetLabelsByRepoID(ctx context.Context, repoID int64, sortType string, listO
|
||||
case "reversealphabetically":
|
||||
sess.Desc("name")
|
||||
case "leastissues":
|
||||
sess.Asc("num_issues")
|
||||
sess.OrderBy("num_issues - num_closed_issues ASC")
|
||||
case "mostissues":
|
||||
sess.Desc("num_issues")
|
||||
sess.OrderBy("num_issues - num_closed_issues DESC")
|
||||
default:
|
||||
sess.Asc("name")
|
||||
}
|
||||
sess.Asc("id")
|
||||
|
||||
if listOptions.Page > 0 {
|
||||
db.SetSessionPagination(sess, &listOptions)
|
||||
@@ -508,12 +509,13 @@ func GetLabelsByOrgID(ctx context.Context, orgID int64, sortType string, listOpt
|
||||
case "reversealphabetically":
|
||||
sess.Desc("name")
|
||||
case "leastissues":
|
||||
sess.Asc("num_issues")
|
||||
sess.OrderBy("num_issues - num_closed_issues ASC")
|
||||
case "mostissues":
|
||||
sess.Desc("num_issues")
|
||||
sess.OrderBy("num_issues - num_closed_issues DESC")
|
||||
default:
|
||||
sess.Asc("name")
|
||||
}
|
||||
sess.Asc("id")
|
||||
|
||||
if listOptions.Page > 0 {
|
||||
db.SetSessionPagination(sess, &listOptions)
|
||||
|
||||
@@ -191,6 +191,8 @@ func TestGetLabelsInRepoByIDs(t *testing.T) {
|
||||
|
||||
func TestGetLabelsByRepoID(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
_, err := db.GetEngine(t.Context()).ID(2).Cols("num_issues", "num_closed_issues").Update(&issues_model.Label{NumIssues: 3, NumClosedIssues: 3})
|
||||
assert.NoError(t, err)
|
||||
testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) {
|
||||
labels, err := issues_model.GetLabelsByRepoID(t.Context(), repoID, sortType, db.ListOptions{})
|
||||
assert.NoError(t, err)
|
||||
@@ -258,6 +260,8 @@ func TestGetLabelsInOrgByIDs(t *testing.T) {
|
||||
|
||||
func TestGetLabelsByOrgID(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
_, err := db.GetEngine(t.Context()).ID(3).Cols("num_issues", "num_closed_issues").Update(&issues_model.Label{NumIssues: 3, NumClosedIssues: 3})
|
||||
assert.NoError(t, err)
|
||||
testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) {
|
||||
labels, err := issues_model.GetLabelsByOrgID(t.Context(), orgID, sortType, db.ListOptions{})
|
||||
assert.NoError(t, err)
|
||||
@@ -271,7 +275,7 @@ func TestGetLabelsByOrgID(t *testing.T) {
|
||||
testSuccess(3, "reversealphabetically", []int64{4, 3})
|
||||
testSuccess(3, "default", []int64{3, 4})
|
||||
|
||||
_, err := issues_model.GetLabelsByOrgID(t.Context(), 0, "leastissues", db.ListOptions{})
|
||||
_, err = issues_model.GetLabelsByOrgID(t.Context(), 0, "leastissues", db.ListOptions{})
|
||||
assert.True(t, issues_model.IsErrOrgLabelNotExist(err))
|
||||
|
||||
_, err = issues_model.GetLabelsByOrgID(t.Context(), -1, "leastissues", db.ListOptions{})
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"errors"
|
||||
"net/http"
|
||||
"slices"
|
||||
|
||||
"gitea.dev/models/db"
|
||||
issues_model "gitea.dev/models/issues"
|
||||
@@ -77,6 +79,16 @@ func RetrieveLabelsForList(ctx *context.Context) {
|
||||
for _, l := range orgLabels {
|
||||
l.CalOpenOrgIssues(ctx, ctx.Repo.Repository.ID, l.ID)
|
||||
}
|
||||
switch ctx.FormString("sort") {
|
||||
case "leastissues":
|
||||
slices.SortStableFunc(orgLabels, func(label1, label2 *issues_model.Label) int {
|
||||
return cmp.Compare(label1.NumOpenRepoIssues, label2.NumOpenRepoIssues)
|
||||
})
|
||||
case "mostissues":
|
||||
slices.SortStableFunc(orgLabels, func(label1, label2 *issues_model.Label) int {
|
||||
return cmp.Compare(label2.NumOpenRepoIssues, label1.NumOpenRepoIssues)
|
||||
})
|
||||
}
|
||||
ctx.Data["OrgLabels"] = orgLabels
|
||||
|
||||
org, err := organization.GetOrgByName(ctx, ctx.Repo.Owner.LowerName)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gitea.dev/models/db"
|
||||
issues_model "gitea.dev/models/issues"
|
||||
"gitea.dev/models/unittest"
|
||||
"gitea.dev/modules/base"
|
||||
@@ -51,14 +52,23 @@ func testInitializeLabels(t *testing.T) {
|
||||
}
|
||||
|
||||
func testRetrieveLabels(t *testing.T) {
|
||||
issueLabel := &issues_model.IssueLabel{IssueID: 6, LabelID: 3}
|
||||
assert.NoError(t, db.Insert(t.Context(), issueLabel))
|
||||
defer func() {
|
||||
_, err := db.DeleteByBean(t.Context(), issueLabel)
|
||||
assert.NoError(t, err)
|
||||
}()
|
||||
|
||||
for _, testCase := range []struct {
|
||||
RepoID int64
|
||||
Sort string
|
||||
ExpectedLabelIDs []int64
|
||||
RepoID int64
|
||||
Sort string
|
||||
ExpectedLabelIDs []int64
|
||||
ExpectedOrgLabelIDs []int64
|
||||
}{
|
||||
{1, "", []int64{1, 2}},
|
||||
{1, "leastissues", []int64{2, 1}},
|
||||
{2, "", []int64{}},
|
||||
{1, "", []int64{1, 2}, nil},
|
||||
{1, "leastissues", []int64{2, 1}, nil},
|
||||
{2, "", nil, nil},
|
||||
{3, "mostissues", []int64{10}, []int64{3, 4}},
|
||||
} {
|
||||
ctx, _ := contexttest.MockContext(t, "user/repo/issues")
|
||||
contexttest.LoadUser(t, ctx, 2)
|
||||
@@ -66,13 +76,15 @@ func testRetrieveLabels(t *testing.T) {
|
||||
ctx.Req.Form.Set("sort", testCase.Sort)
|
||||
RetrieveLabelsForList(ctx)
|
||||
assert.False(t, ctx.Written())
|
||||
labels, ok := ctx.Data["Labels"].([]*issues_model.Label)
|
||||
assert.True(t, ok)
|
||||
if assert.Len(t, labels, len(testCase.ExpectedLabelIDs)) {
|
||||
for i, label := range labels {
|
||||
assert.Equal(t, testCase.ExpectedLabelIDs[i], label.ID)
|
||||
labelIDs := func(key string) (ids []int64) {
|
||||
labels, _ := ctx.Data[key].([]*issues_model.Label)
|
||||
for _, label := range labels {
|
||||
ids = append(ids, label.ID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
assert.Equal(t, testCase.ExpectedLabelIDs, labelIDs("Labels"))
|
||||
assert.Equal(t, testCase.ExpectedOrgLabelIDs, labelIDs("OrgLabels"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user