Skip to content

Commit 6d93a3a

Browse files
silverwindlafriks
andauthored
Issue and Pulls lists rework (#13594)
* Issue and Pulls lists rework Reorganized and restyled the issue and pull request lists. * color and layout tweaks * use new issue list on dashboard as well * move pagination into template * misc tweaks * fix label hover * fix milestone list * fix discrepancies between issue and milestone list, add new 'merge' helper * fmt * simplify merge helper * remove whitespace * fix startIndex * further simplify dict merging * rename helper to 'mergeinto' for clarity * allow bottom-row to wrap Co-authored-by: Lauris BH <[email protected]>
1 parent 00ec651 commit 6d93a3a

File tree

12 files changed

+341
-478
lines changed

12 files changed

+341
-478
lines changed

modules/templates/helper.go

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -256,31 +256,27 @@ func NewFuncMap() []template.FuncMap {
256256
"DefaultTheme": func() string {
257257
return setting.UI.DefaultTheme
258258
},
259+
// pass key-value pairs to a partial template which receives them as a dict
259260
"dict": func(values ...interface{}) (map[string]interface{}, error) {
260261
if len(values) == 0 {
261262
return nil, errors.New("invalid dict call")
262263
}
263264

264265
dict := make(map[string]interface{})
266+
return util.MergeInto(dict, values...)
267+
},
268+
/* like dict but merge key-value pairs into the first dict and return it */
269+
"mergeinto": func(root map[string]interface{}, values ...interface{}) (map[string]interface{}, error) {
270+
if len(values) == 0 {
271+
return nil, errors.New("invalid mergeinto call")
272+
}
265273

266-
for i := 0; i < len(values); i++ {
267-
switch key := values[i].(type) {
268-
case string:
269-
i++
270-
if i == len(values) {
271-
return nil, errors.New("specify the key for non array values")
272-
}
273-
dict[key] = values[i]
274-
case map[string]interface{}:
275-
m := values[i].(map[string]interface{})
276-
for i, v := range m {
277-
dict[i] = v
278-
}
279-
default:
280-
return nil, errors.New("dict values must be maps")
281-
}
274+
dict := make(map[string]interface{})
275+
for key, value := range root {
276+
dict[key] = value
282277
}
283-
return dict, nil
278+
279+
return util.MergeInto(dict, values...)
284280
},
285281
"percentage": func(n int, values ...int) float32 {
286282
var sum = 0

modules/util/util.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package util
66

77
import (
88
"bytes"
9+
"errors"
910
"strings"
1011
)
1112

@@ -100,3 +101,26 @@ func NormalizeEOL(input []byte) []byte {
100101
}
101102
return tmp[:pos]
102103
}
104+
105+
// MergeInto merges pairs of values into a "dict"
106+
func MergeInto(dict map[string]interface{}, values ...interface{}) (map[string]interface{}, error) {
107+
for i := 0; i < len(values); i++ {
108+
switch key := values[i].(type) {
109+
case string:
110+
i++
111+
if i == len(values) {
112+
return nil, errors.New("specify the key for non array values")
113+
}
114+
dict[key] = values[i]
115+
case map[string]interface{}:
116+
m := values[i].(map[string]interface{})
117+
for i, v := range m {
118+
dict[i] = v
119+
}
120+
default:
121+
return nil, errors.New("dict values must be maps")
122+
}
123+
}
124+
125+
return dict, nil
126+
}

templates/repo/issue/list.tmpl

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -200,106 +200,7 @@
200200
</div>
201201
</div>
202202
</div>
203-
204-
<div class="issue list">
205-
{{ $approvalCounts := .ApprovalCounts}}
206-
{{range .Issues}}
207-
<li class="item">
208-
{{if $.CanWriteIssuesOrPulls}}
209-
<div class="ui checkbox issue-checkbox">
210-
<input type="checkbox" data-issue-id={{.ID}}></input>
211-
</div>
212-
{{end}}
213-
<div class="ui {{if .IsClosed}}{{if .IsPull}}{{if .PullRequest.HasMerged}}purple{{else}}red{{end}}{{else}}red{{end}}{{else}}{{if .IsRead}}white{{else}}green{{end}}{{end}} label">#{{.Index}}</div>
214-
<a class="title" href="{{$.Link}}/{{.Index}}">{{RenderEmoji .Title}}</a>
215-
216-
{{if .IsPull }}
217-
{{if (index $.CommitStatus .PullRequest.ID)}}
218-
{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
219-
{{end}}
220-
{{end}}
221-
222-
{{range .Labels}}
223-
<a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}" title="{{.Description | RenderEmojiPlain}}">{{.Name | RenderEmoji}}</a>
224-
{{end}}
225-
226-
{{if .NumComments}}
227-
<span class="comment ui right">{{svg "octicon-comment"}} {{.NumComments}}</span>
228-
{{end}}
229-
230-
{{if .TotalTrackedTime}}
231-
<span class="comment ui right">{{svg "octicon-clock"}} {{.TotalTrackedTime | Sec2Time}}</span>
232-
{{end}}
233-
234-
<p class="desc">
235-
{{ $timeStr := TimeSinceUnix .GetLastEventTimestamp $.Lang }}
236-
{{if .OriginalAuthor }}
237-
{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
238-
{{else if gt .Poster.ID 0}}
239-
{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName | Escape) | Safe}}
240-
{{else}}
241-
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
242-
{{end}}
243-
244-
{{if .Milestone}}
245-
<a class="milestone" href="{{$.RepoLink}}/milestone/{{.Milestone.ID}}">
246-
{{svg "octicon-milestone"}} {{.Milestone.Name}}
247-
</a>
248-
{{end}}
249-
{{if .Ref}}
250-
<a class="ref" href="{{index $.IssueRefURLs .ID}}">
251-
{{svg "octicon-git-branch"}} {{index $.IssueRefEndNames .ID}}
252-
</a>
253-
{{end}}
254-
{{$tasks := .GetTasks}}
255-
{{if gt $tasks 0}}
256-
{{$tasksDone := .GetTasksDone}}
257-
<span class="checklist">
258-
{{svg "octicon-checklist"}} {{$tasksDone}} / {{$tasks}} <span class="progress-bar"><span class="progress" style="width:calc(100% * {{$tasksDone}} / {{$tasks}});"></span></span>
259-
</span>
260-
{{end}}
261-
{{if ne .DeadlineUnix 0}}
262-
<span class="due-date poping up" data-content="{{$.i18n.Tr "repo.issues.due_date"}}" data-variation="tiny inverted" data-position="right center">
263-
{{svg "octicon-calendar"}}<span{{if .IsOverdue}} class="overdue"{{end}}>{{.DeadlineUnix.FormatShort}}</span>
264-
</span>
265-
{{end}}
266-
{{range .Assignees}}
267-
<a class="ui right assignee poping up" href="{{.HomeLink}}" data-content="{{.GetDisplayName}}" data-variation="inverted" data-position="left center">
268-
<img class="ui avatar image" src="{{.RelAvatarLink}}">
269-
</a>
270-
{{end}}
271-
{{if .IsPull}}
272-
{{$approveOfficial := call $approvalCounts .ID "approve"}}
273-
{{$rejectOfficial := call $approvalCounts .ID "reject"}}
274-
{{$waitingOfficial := call $approvalCounts .ID "waiting"}}
275-
{{if gt $approveOfficial 0}}
276-
<span class="approvals">{{svg "octicon-check"}}
277-
{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
278-
</span>
279-
{{end}}
280-
281-
{{if gt $rejectOfficial 0}}
282-
<span class="rejects">{{svg "octicon-diff"}}
283-
{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
284-
</span>
285-
{{end}}
286-
287-
{{if gt $waitingOfficial 0}}
288-
<span class="waiting">{{svg "octicon-eye"}}
289-
{{$.i18n.Tr (TrN $.i18n.Lang $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n") $waitingOfficial}}
290-
</span>
291-
{{end}}
292-
293-
{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
294-
<span class="conflicting">{{svg "octicon-x"}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}}</span>
295-
{{end}}
296-
{{end}}
297-
</p>
298-
</li>
299-
{{end}}
300-
301-
{{template "base/paginate" .}}
302-
</div>
203+
{{template "shared/issuelist" mergeinto . "listType" "repo"}}
303204
</div>
304205
</div>
305206
{{template "base/footer" .}}

templates/repo/issue/milestone_issues.tmpl

Lines changed: 1 addition & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -177,127 +177,7 @@
177177
</div>
178178
</div>
179179
</div>
180-
181-
<div class="issue list">
182-
{{ $approvalCounts := .ApprovalCounts}}
183-
{{range .Issues}}
184-
{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
185-
<li class="item">
186-
{{if or (and $.CanWriteIssues (not .IsPull)) (and $.CanWritePulls .IsPull)}}
187-
<div class="ui checkbox issue-checkbox">
188-
<input type="checkbox" data-issue-id={{.ID}}></input>
189-
</div>
190-
{{end}}
191-
192-
{{if .IsClosed}}
193-
{{if .IsPull}}
194-
{{if .PullRequest.HasMerged}}
195-
<div class="ui purple label">#{{.Index}}</div>
196-
<a class="ui purple text">{{svg "octicon-git-pull-request"}}</a>
197-
{{else}}
198-
<div class="ui red label">#{{.Index}}</div>
199-
<a class="ui red text">{{svg "octicon-git-pull-request"}}</a>
200-
{{end}}
201-
{{else}}
202-
<div class="ui red label">#{{.Index}}</div>
203-
<a class="ui red text">{{svg "octicon-issue-closed"}}</a>
204-
{{end}}
205-
{{else}}
206-
{{if .IsRead}}
207-
<div class="ui white label">#{{.Index}}</div>
208-
{{else}}
209-
<div class="ui green label">#{{.Index}}</div>
210-
{{end}}
211-
{{if .IsPull}}
212-
<a class="ui green text">{{svg "octicon-git-pull-request"}}</a>
213-
{{else}}
214-
<a class="ui green text">{{svg "octicon-issue-opened"}}</a>
215-
{{end}}
216-
{{end}}
217-
218-
<a class="title" href="{{$.RepoLink}}/issues/{{.Index}}">{{.Title | RenderEmoji}}</a>
219-
220-
{{if .IsPull }}
221-
{{if (index $.CommitStatus .PullRequest.ID)}}
222-
{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
223-
{{end}}
224-
{{end}}
225-
226-
{{range .Labels}}
227-
<a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}" title="{{.Description}}">{{.Name | RenderEmoji}}</a>
228-
{{end}}
229-
230-
{{if .NumComments}}
231-
<span class="comment ui right">{{svg "octicon-comment"}} {{.NumComments}}</span>
232-
{{end}}
233-
234-
{{if .TotalTrackedTime}}
235-
<span class="comment ui right">{{svg "octicon-clock"}} {{.TotalTrackedTime | Sec2Time}}</span>
236-
{{end}}
237-
238-
<p class="desc">
239-
{{ $timeStr := TimeSinceUnix .GetLastEventTimestamp $.Lang }}
240-
{{if .OriginalAuthor }}
241-
{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
242-
{{else if gt .Poster.ID 0}}
243-
{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName | Escape) | Safe}}
244-
{{else}}
245-
{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
246-
{{end}}
247-
248-
{{if .Ref}}
249-
<a class="ref" href="{{index $.IssueRefURLs .ID}}">
250-
{{svg "octicon-git-branch"}} {{index $.IssueRefEndNames .ID}}
251-
</a>
252-
{{end}}
253-
{{$tasks := .GetTasks}}
254-
{{if gt $tasks 0}}
255-
{{$tasksDone := .GetTasksDone}}
256-
<span class="checklist">
257-
{{svg "octicon-checklist"}} {{$tasksDone}} / {{$tasks}} <span class="progress-bar"><span class="progress" style="width:calc(100% * {{$tasksDone}} / {{$tasks}});"></span></span>
258-
</span>
259-
{{end}}
260-
{{if ne .DeadlineUnix 0}}
261-
{{svg "octicon-calendar"}}
262-
<span{{if .IsOverdue}} class="overdue"{{end}}>{{.DeadlineUnix.FormatShort}}</span>
263-
{{end}}
264-
{{range .Assignees}}
265-
<a class="ui right assignee poping up" href="{{.HomeLink}}" data-content="{{.GetDisplayName}}" data-variation="inverted" data-position="left center">
266-
<img class="ui avatar image" src="{{.RelAvatarLink}}">
267-
</a>
268-
{{end}}
269-
{{if .IsPull}}
270-
{{$approveOfficial := call $approvalCounts .ID "approve"}}
271-
{{$rejectOfficial := call $approvalCounts .ID "reject"}}
272-
{{$waitingOfficial := call $approvalCounts .ID "waiting"}}
273-
{{if gt $approveOfficial 0}}
274-
<span class="approvals">{{svg "octicon-check"}}
275-
{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
276-
</span>
277-
{{end}}
278-
279-
{{if gt $rejectOfficial 0}}
280-
<span class="rejects">{{svg "octicon-diff"}}
281-
{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
282-
</span>
283-
{{end}}
284-
285-
{{if gt $waitingOfficial 0}}
286-
<span class="waiting">{{svg "octicon-eye"}}
287-
{{$.i18n.Tr (TrN $.i18n.Lang $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n") $waitingOfficial}}
288-
</span>
289-
{{end}}
290-
291-
{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
292-
<span class="conflicting">{{svg "octicon-x"}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}}</span>
293-
{{end}}
294-
{{end}}
295-
</p>
296-
</li>
297-
{{end}}
298-
299-
{{template "base/paginate" .}}
300-
</div>
180+
{{template "shared/issuelist" mergeinto . "listType" "milestone"}}
301181
</div>
302182
</div>
303183
{{template "base/footer" .}}

0 commit comments

Comments
 (0)