Skip to content

Commit 722865a

Browse files
lunnyGiteaBot
authored andcommitted
Improve milestone filter on issues page (go-gitea#22423)
Now we have `All milestones`, `No milestones`, `Open milestones` and `Closed milestones`. Fix go-gitea#11924 Fix go-gitea#22411 <img width="1166" alt="image" src="https://user-images.githubusercontent.com/81045/212243375-95eea035-a972-44b8-8088-53db614cb07e.png">
1 parent d9d3f52 commit 722865a

File tree

8 files changed

+99
-91
lines changed

8 files changed

+99
-91
lines changed

models/db/search.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ const (
3131
const (
3232
// Which means a condition to filter the records which don't match any id.
3333
// It's different from zero which means the condition could be ignored.
34-
NoneID = -1
34+
NoConditionID = -1
3535
)

models/issues/issue.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,9 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
12661266
applySubscribedCondition(sess, opts.SubscriberID)
12671267
}
12681268

1269-
if len(opts.MilestoneIDs) > 0 {
1269+
if len(opts.MilestoneIDs) == 1 && opts.MilestoneIDs[0] == db.NoConditionID {
1270+
sess.And("issue.milestone_id = 0")
1271+
} else if len(opts.MilestoneIDs) > 0 {
12701272
sess.In("issue.milestone_id", opts.MilestoneIDs)
12711273
}
12721274

@@ -1280,7 +1282,7 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
12801282
if opts.ProjectID > 0 {
12811283
sess.Join("INNER", "project_issue", "issue.id = project_issue.issue_id").
12821284
And("project_issue.project_id=?", opts.ProjectID)
1283-
} else if opts.ProjectID == db.NoneID { // show those that are in no project
1285+
} else if opts.ProjectID == db.NoConditionID { // show those that are in no project
12841286
sess.And(builder.NotIn("issue.id", builder.Select("issue_id").From("project_issue")))
12851287
}
12861288

@@ -1680,6 +1682,8 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
16801682

16811683
if opts.MilestoneID > 0 {
16821684
sess.And("issue.milestone_id = ?", opts.MilestoneID)
1685+
} else if opts.MilestoneID == db.NoConditionID {
1686+
sess.And("issue.milestone_id = 0")
16831687
}
16841688

16851689
if opts.ProjectID > 0 {

options/locale/locale_en-US.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,10 @@ issues.filter_label = Label
13101310
issues.filter_label_exclude = `Use <code>alt</code> + <code>click/enter</code> to exclude labels`
13111311
issues.filter_label_no_select = All labels
13121312
issues.filter_milestone = Milestone
1313-
issues.filter_milestone_no_select = All milestones
1313+
issues.filter_milestone_all = All milestones
1314+
issues.filter_milestone_none = No milestones
1315+
issues.filter_milestone_open = Open milestones
1316+
issues.filter_milestone_closed = Closed milestones
13141317
issues.filter_project = Project
13151318
issues.filter_project_all = All projects
13161319
issues.filter_project_none = No project

routers/web/repo/issue.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
237237
pager := context.NewPagination(total, setting.UI.IssuePagingNum, page, 5)
238238

239239
var mileIDs []int64
240-
if milestoneID > 0 {
240+
if milestoneID > 0 || milestoneID == db.NoConditionID { // -1 to get those issues which have no any milestone assigned
241241
mileIDs = []int64{milestoneID}
242242
}
243243

@@ -438,20 +438,37 @@ func Issues(ctx *context.Context) {
438438
return
439439
}
440440

441-
var err error
441+
renderMilestones(ctx)
442+
if ctx.Written() {
443+
return
444+
}
445+
446+
ctx.Data["CanWriteIssuesOrPulls"] = ctx.Repo.CanWriteIssuesOrPulls(isPullList)
447+
448+
ctx.HTML(http.StatusOK, tplIssues)
449+
}
450+
451+
func renderMilestones(ctx *context.Context) {
442452
// Get milestones
443-
ctx.Data["Milestones"], _, err = issues_model.GetMilestones(issues_model.GetMilestonesOption{
453+
milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{
444454
RepoID: ctx.Repo.Repository.ID,
445-
State: api.StateType(ctx.FormString("state")),
455+
State: api.StateAll,
446456
})
447457
if err != nil {
448458
ctx.ServerError("GetAllRepoMilestones", err)
449459
return
450460
}
451461

452-
ctx.Data["CanWriteIssuesOrPulls"] = ctx.Repo.CanWriteIssuesOrPulls(isPullList)
453-
454-
ctx.HTML(http.StatusOK, tplIssues)
462+
openMilestones, closedMilestones := issues_model.MilestoneList{}, issues_model.MilestoneList{}
463+
for _, milestone := range milestones {
464+
if milestone.IsClosed {
465+
closedMilestones = append(closedMilestones, milestone)
466+
} else {
467+
openMilestones = append(openMilestones, milestone)
468+
}
469+
}
470+
ctx.Data["OpenMilestones"] = openMilestones
471+
ctx.Data["ClosedMilestones"] = closedMilestones
455472
}
456473

457474
// RetrieveRepoMilestonesAndAssignees find all the milestones and assignees of a repository

templates/repo/issue/list.tmpl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
</div>
6464

6565
<!-- Milestone -->
66-
<div class="ui {{if not .Milestones}}disabled{{end}} dropdown jump item">
66+
<div class="ui {{if not (or .OpenMilestones .ClosedMilestones)}}disabled{{end}} dropdown jump item">
6767
<span class="text">
6868
{{.locale.Tr "repo.issues.filter_milestone"}}
6969
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
@@ -73,9 +73,28 @@
7373
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
7474
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_milestone"}}">
7575
</div>
76-
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_milestone_no_select"}}</a>
77-
{{range .Milestones}}
78-
<a class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected{{end}}{{end}} item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.Name}}</a>
76+
<div class="divider"></div>
77+
<a class="{{if not $.MilestoneID}}active selected {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=0&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_milestone_all"}}</a>
78+
<a class="{{if $.MilestoneID}}{{if eq $.MilestoneID -1}}active selected {{end}}{{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone=-1&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_milestone_none"}}</a>
79+
{{if .OpenMilestones}}
80+
<div class="divider"></div>
81+
<div class="header">{{.locale.Tr "repo.issues.filter_milestone_open"}}</div>
82+
{{range .OpenMilestones}}
83+
<a class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">
84+
{{svg "octicon-milestone" 16 "mr-2"}}
85+
{{.Name}}
86+
</a>
87+
{{end}}
88+
{{end}}
89+
{{if .ClosedMilestones}}
90+
<div class="divider"></div>
91+
<div class="header">{{.locale.Tr "repo.issues.filter_milestone_closed"}}</div>
92+
{{range .ClosedMilestones}}
93+
<a class="{{if $.MilestoneID}}{{if eq $.MilestoneID .ID}}active selected {{end}}{{end}}item" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{.ID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">
94+
{{svg "octicon-milestone" 16 "mr-2"}}
95+
{{.Name}}
96+
</a>
97+
{{end}}
7998
{{end}}
8099
</div>
81100
</div>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_milestone_title"}}</div>
2+
{{if or .OpenMilestones .ClosedMilestones}}
3+
<div class="ui icon search input">
4+
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
5+
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_milestones"}}">
6+
</div>
7+
<div class="divider"></div>
8+
{{end}}
9+
<div class="no-select item">{{.locale.Tr "repo.issues.new.clear_milestone"}}</div>
10+
{{if and (not .OpenMilestones) (not .ClosedMilestones)}}
11+
<div class="header" style="text-transform: none;font-size:14px;">
12+
{{.locale.Tr "repo.issues.new.no_items"}}
13+
</div>
14+
{{else}}
15+
{{if .OpenMilestones}}
16+
<div class="divider"></div>
17+
<div class="header">
18+
{{.locale.Tr "repo.issues.new.open_milestone"}}
19+
</div>
20+
{{range .OpenMilestones}}
21+
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
22+
{{svg "octicon-milestone" 16 "gt-mr-2"}}
23+
{{.Name}}
24+
</a>
25+
{{end}}
26+
{{end}}
27+
{{if .ClosedMilestones}}
28+
<div class="divider"></div>
29+
<div class="header">
30+
{{.locale.Tr "repo.issues.new.closed_milestone"}}
31+
</div>
32+
{{range .ClosedMilestones}}
33+
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
34+
{{svg "octicon-milestone" 16 "gt-mr-2"}}
35+
{{.Name}}
36+
</a>
37+
{{end}}
38+
{{end}}
39+
{{end}}

templates/repo/issue/new_form.tmpl

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -93,44 +93,7 @@
9393
{{end}}
9494
</span>
9595
<div class="menu">
96-
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_milestone_title"}}</div>
97-
{{if or .OpenMilestones .ClosedMilestones}}
98-
<div class="ui icon search input">
99-
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
100-
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_milestones"}}">
101-
</div>
102-
{{end}}
103-
<div class="no-select item">{{.locale.Tr "repo.issues.new.clear_milestone"}}</div>
104-
{{if and (not .OpenMilestones) (not .ClosedMilestones)}}
105-
<div class="header" style="text-transform: none;font-size:14px;">
106-
{{.locale.Tr "repo.issues.new.no_items"}}
107-
</div>
108-
{{else}}
109-
{{if .OpenMilestones}}
110-
<div class="divider"></div>
111-
<div class="header">
112-
{{.locale.Tr "repo.issues.new.open_milestone"}}
113-
</div>
114-
{{range .OpenMilestones}}
115-
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
116-
{{svg "octicon-milestone" 16 "gt-mr-2"}}
117-
{{.Name}}
118-
</a>
119-
{{end}}
120-
{{end}}
121-
{{if .ClosedMilestones}}
122-
<div class="divider"></div>
123-
<div class="header">
124-
{{.locale.Tr "repo.issues.new.closed_milestone"}}
125-
</div>
126-
{{range .ClosedMilestones}}
127-
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
128-
{{svg "octicon-milestone" 16 "gt-mr-2"}}
129-
{{.Name}}
130-
</a>
131-
{{end}}
132-
{{end}}
133-
{{end}}
96+
{{template "repo/issue/milestone/select_menu" .}}
13497
</div>
13598
</div>
13699
<div class="ui select-milestone list">

templates/repo/issue/view_content/sidebar.tmpl

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -161,44 +161,7 @@
161161
{{end}}
162162
</a>
163163
<div class="menu" data-action="update" data-issue-id="{{$.Issue.ID}}" data-update-url="{{$.RepoLink}}/issues/milestone">
164-
<div class="header" style="text-transform: none;font-size:16px;">{{.locale.Tr "repo.issues.new.add_milestone_title"}}</div>
165-
{{if or .OpenMilestones .ClosedMilestones}}
166-
<div class="ui icon search input">
167-
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
168-
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_milestones"}}">
169-
</div>
170-
{{end}}
171-
<div class="no-select item">{{.locale.Tr "repo.issues.new.clear_milestone"}}</div>
172-
{{if and (not .OpenMilestones) (not .ClosedMilestones)}}
173-
<div class="header" style="text-transform: none;font-size:14px;">
174-
{{.locale.Tr "repo.issues.new.no_items"}}
175-
</div>
176-
{{else}}
177-
{{if .OpenMilestones}}
178-
<div class="divider"></div>
179-
<div class="header">
180-
{{.locale.Tr "repo.issues.new.open_milestone"}}
181-
</div>
182-
{{range .OpenMilestones}}
183-
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
184-
{{svg "octicon-milestone" 16 "gt-mr-2"}}
185-
{{.Name}}
186-
</a>
187-
{{end}}
188-
{{end}}
189-
{{if .ClosedMilestones}}
190-
<div class="divider"></div>
191-
<div class="header">
192-
{{.locale.Tr "repo.issues.new.closed_milestone"}}
193-
</div>
194-
{{range .ClosedMilestones}}
195-
<a class="item" data-id="{{.ID}}" data-href="{{$.RepoLink}}/issues?milestone={{.ID}}">
196-
{{svg "octicon-milestone" 16 "gt-mr-2"}}
197-
{{.Name}}
198-
</a>
199-
{{end}}
200-
{{end}}
201-
{{end}}
164+
{{template "repo/issue/milestone/select_menu" .}}
202165
</div>
203166
</div>
204167
<div class="ui select-milestone list">

0 commit comments

Comments
 (0)