[API] Issue Search Add filter for MilestoneNames (#16173)

release/v1.15
6543 2021-06-17 08:40:59 +02:00 committed by GitHub
parent fdf9ab11cd
commit 9469e14dc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 1 deletions

View File

@ -222,6 +222,20 @@ func TestAPISearchIssues(t *testing.T) {
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues) DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 1) assert.Len(t, apiIssues, 1)
query = url.Values{"milestones": {"milestone1"}, "state": {"all"}}
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 1)
query = url.Values{"milestones": {"milestone1,milestone3"}, "state": {"all"}}
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
} }
func TestAPISearchIssuesWithLabels(t *testing.T) { func TestAPISearchIssuesWithLabels(t *testing.T) {

View File

@ -1100,6 +1100,7 @@ type IssuesOptions struct {
LabelIDs []int64 LabelIDs []int64
IncludedLabelNames []string IncludedLabelNames []string
ExcludedLabelNames []string ExcludedLabelNames []string
IncludeMilestones []string
SortType string SortType string
IssueIDs []int64 IssueIDs []int64
UpdatedAfterUnix int64 UpdatedAfterUnix int64
@ -1241,6 +1242,13 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) {
if len(opts.ExcludedLabelNames) > 0 { if len(opts.ExcludedLabelNames) > 0 {
sess.And(builder.NotIn("issue.id", BuildLabelNamesIssueIDsCondition(opts.ExcludedLabelNames))) sess.And(builder.NotIn("issue.id", BuildLabelNamesIssueIDsCondition(opts.ExcludedLabelNames)))
} }
if len(opts.IncludeMilestones) > 0 {
sess.In("issue.milestone_id",
builder.Select("id").
From("milestone").
Where(builder.In("name", opts.IncludeMilestones)))
}
} }
func applyReposCondition(sess *xorm.Session, repoIDs []int64) *xorm.Session { func applyReposCondition(sess *xorm.Session, repoIDs []int64) *xorm.Session {

View File

@ -42,6 +42,10 @@ func SearchIssues(ctx *context.APIContext) {
// in: query // in: query
// description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded // description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded
// type: string // type: string
// - name: milestones
// in: query
// description: comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded
// type: string
// - name: q // - name: q
// in: query // in: query
// description: search string // description: search string
@ -164,6 +168,12 @@ func SearchIssues(ctx *context.APIContext) {
includedLabelNames = strings.Split(labels, ",") includedLabelNames = strings.Split(labels, ",")
} }
milestones := strings.TrimSpace(ctx.Query("milestones"))
var includedMilestones []string
if len(milestones) > 0 {
includedMilestones = strings.Split(milestones, ",")
}
// this api is also used in UI, // this api is also used in UI,
// so the default limit is set to fit UI needs // so the default limit is set to fit UI needs
limit := ctx.QueryInt("limit") limit := ctx.QueryInt("limit")
@ -175,7 +185,7 @@ func SearchIssues(ctx *context.APIContext) {
// Only fetch the issues if we either don't have a keyword or the search returned issues // Only fetch the issues if we either don't have a keyword or the search returned issues
// This would otherwise return all issues if no issues were found by the search. // This would otherwise return all issues if no issues were found by the search.
if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 { if len(keyword) == 0 || len(issueIDs) > 0 || len(includedLabelNames) > 0 || len(includedMilestones) > 0 {
issuesOpt := &models.IssuesOptions{ issuesOpt := &models.IssuesOptions{
ListOptions: models.ListOptions{ ListOptions: models.ListOptions{
Page: ctx.QueryInt("page"), Page: ctx.QueryInt("page"),
@ -185,6 +195,7 @@ func SearchIssues(ctx *context.APIContext) {
IsClosed: isClosed, IsClosed: isClosed,
IssueIDs: issueIDs, IssueIDs: issueIDs,
IncludedLabelNames: includedLabelNames, IncludedLabelNames: includedLabelNames,
IncludeMilestones: includedMilestones,
SortType: "priorityrepo", SortType: "priorityrepo",
PriorityRepoID: ctx.QueryInt64("priority_repo_id"), PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
IsPull: isPull, IsPull: isPull,

View File

@ -1876,6 +1876,12 @@
"name": "labels", "name": "labels",
"in": "query" "in": "query"
}, },
{
"type": "string",
"description": "comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded",
"name": "milestones",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "search string", "description": "search string",