mirror of
https://github.com/go-gitea/gitea
synced 2024-12-22 16:44:26 +00:00
parent
a88f718c10
commit
00fc29aee1
@ -118,29 +118,29 @@ func applyLabelsCondition(sess *xorm.Session, opts *IssuesOptions) {
|
|||||||
if opts.LabelIDs[0] == 0 {
|
if opts.LabelIDs[0] == 0 {
|
||||||
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label)")
|
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label)")
|
||||||
} else {
|
} else {
|
||||||
// We sort and deduplicate the labels' ids
|
// deduplicate the label IDs for inclusion and exclusion
|
||||||
IncludedLabelIDs := make(container.Set[int64])
|
includedLabelIDs := make(container.Set[int64])
|
||||||
ExcludedLabelIDs := make(container.Set[int64])
|
excludedLabelIDs := make(container.Set[int64])
|
||||||
for _, labelID := range opts.LabelIDs {
|
for _, labelID := range opts.LabelIDs {
|
||||||
if labelID > 0 {
|
if labelID > 0 {
|
||||||
IncludedLabelIDs.Add(labelID)
|
includedLabelIDs.Add(labelID)
|
||||||
} else if labelID < 0 { // 0 is not supported here, so just ignore it
|
} else if labelID < 0 { // 0 is not supported here, so just ignore it
|
||||||
ExcludedLabelIDs.Add(-labelID)
|
excludedLabelIDs.Add(-labelID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ... and use them in a subquery of the form :
|
// ... and use them in a subquery of the form :
|
||||||
// where (select count(*) from issue_label where issue_id=issue.id and label_id in (2, 4, 6)) = 3
|
// where (select count(*) from issue_label where issue_id=issue.id and label_id in (2, 4, 6)) = 3
|
||||||
// This equality is guaranteed thanks to unique index (issue_id,label_id) on table issue_label.
|
// This equality is guaranteed thanks to unique index (issue_id,label_id) on table issue_label.
|
||||||
if len(IncludedLabelIDs) > 0 {
|
if len(includedLabelIDs) > 0 {
|
||||||
subquery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
|
subQuery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
|
||||||
And(builder.In("label_id", IncludedLabelIDs.Values()))
|
And(builder.In("label_id", includedLabelIDs.Values()))
|
||||||
sess.Where(builder.Eq{strconv.Itoa(len(IncludedLabelIDs)): subquery})
|
sess.Where(builder.Eq{strconv.Itoa(len(includedLabelIDs)): subQuery})
|
||||||
}
|
}
|
||||||
// or (select count(*)...) = 0 for excluded labels
|
// or (select count(*)...) = 0 for excluded labels
|
||||||
if len(ExcludedLabelIDs) > 0 {
|
if len(excludedLabelIDs) > 0 {
|
||||||
subquery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
|
subQuery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
|
||||||
And(builder.In("label_id", ExcludedLabelIDs.Values()))
|
And(builder.In("label_id", excludedLabelIDs.Values()))
|
||||||
sess.Where(builder.Eq{"0": subquery})
|
sess.Where(builder.Eq{"0": subQuery})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
|
"code.gitea.io/gitea/modules/container"
|
||||||
"code.gitea.io/gitea/modules/label"
|
"code.gitea.io/gitea/modules/label"
|
||||||
"code.gitea.io/gitea/modules/optional"
|
"code.gitea.io/gitea/modules/optional"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
@ -143,37 +144,32 @@ func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
|
|||||||
|
|
||||||
// LoadSelectedLabelsAfterClick calculates the set of selected labels when a label is clicked
|
// LoadSelectedLabelsAfterClick calculates the set of selected labels when a label is clicked
|
||||||
func (l *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64, currentSelectedExclusiveScopes []string) {
|
func (l *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64, currentSelectedExclusiveScopes []string) {
|
||||||
labelQuerySlice := []int64{}
|
labelQueryParams := container.Set[string]{}
|
||||||
labelSelected := false
|
labelSelected := false
|
||||||
labelScope := l.ExclusiveScope()
|
exclusiveScope := l.ExclusiveScope()
|
||||||
for i, s := range currentSelectedLabels {
|
for i, curSel := range currentSelectedLabels {
|
||||||
if s == l.ID {
|
if curSel == l.ID {
|
||||||
labelSelected = true
|
labelSelected = true
|
||||||
} else if -s == l.ID {
|
} else if -curSel == l.ID {
|
||||||
labelSelected = true
|
labelSelected = true
|
||||||
l.IsExcluded = true
|
l.IsExcluded = true
|
||||||
} else if s != 0 {
|
} else if curSel != 0 {
|
||||||
// Exclude other labels in the same scope from selection
|
// Exclude other labels in the same scope from selection
|
||||||
if s < 0 || labelScope == "" || labelScope != currentSelectedExclusiveScopes[i] {
|
if curSel < 0 || exclusiveScope == "" || exclusiveScope != currentSelectedExclusiveScopes[i] {
|
||||||
labelQuerySlice = append(labelQuerySlice, s)
|
labelQueryParams.Add(strconv.FormatInt(curSel, 10))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !labelSelected {
|
if !labelSelected {
|
||||||
labelQuerySlice = append(labelQuerySlice, l.ID)
|
labelQueryParams.Add(strconv.FormatInt(l.ID, 10))
|
||||||
}
|
}
|
||||||
l.IsSelected = labelSelected
|
l.IsSelected = labelSelected
|
||||||
|
|
||||||
// Sort and deduplicate the ids to avoid the crawlers asking for the
|
// Sort and deduplicate the ids to avoid the crawlers asking for the
|
||||||
// same thing with simply a different order of parameters
|
// same thing with simply a different order of parameters
|
||||||
slices.Sort(labelQuerySlice)
|
labelQuerySliceStrings := labelQueryParams.Values()
|
||||||
labelQuerySlice = slices.Compact(labelQuerySlice)
|
slices.Sort(labelQuerySliceStrings) // the sort is still needed because the underlying map of Set doesn't guarantee order
|
||||||
// Quick conversion (strings.Join() doesn't accept slices of Int64)
|
|
||||||
labelQuerySliceStrings := make([]string, len(labelQuerySlice))
|
|
||||||
for i, x := range labelQuerySlice {
|
|
||||||
labelQuerySliceStrings[i] = strconv.FormatInt(x, 10)
|
|
||||||
}
|
|
||||||
l.QueryString = strings.Join(labelQuerySliceStrings, ",")
|
l.QueryString = strings.Join(labelQuerySliceStrings, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +183,7 @@ func (l *Label) BelongsToRepo() bool {
|
|||||||
return l.RepoID > 0
|
return l.RepoID > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return scope substring of label name, or empty string if none exists
|
// ExclusiveScope returns scope substring of label name, or empty string if none exists
|
||||||
func (l *Label) ExclusiveScope() string {
|
func (l *Label) ExclusiveScope() string {
|
||||||
if !l.Exclusive {
|
if !l.Exclusive {
|
||||||
return ""
|
return ""
|
||||||
|
Loading…
Reference in New Issue
Block a user