internal/httpd/facets.go
82 lines · 2396 bytes
1package httpd
2
3import (
4 "net/url"
5
6 "gitbay.org/gitbay/internal/store"
7)
8
9// facetItem is one link in a list page's side column: a value the list
10// narrows to. Clicking an active item clears it.
11type facetItem struct {
12 Label string
13 Count int64
14 Href string
15 Active bool
16}
17
18// facetGroup is one heading in the column: State, Labels, Milestones.
19type facetGroup struct {
20 Title string
21 Items []facetItem
22}
23
24// facetHref returns "?..." with every parameter of base kept, key set to
25// value, or dropped when value is "". url.Values encodes sorted, so the
26// tests and the links agree byte for byte.
27func facetHref(base url.Values, key, value string) string {
28 q := url.Values{}
29 for k, vs := range base {
30 if k == key || len(vs) == 0 || vs[0] == "" {
31 continue
32 }
33 q.Set(k, vs[0])
34 }
35 if value != "" {
36 q.Set(key, value)
37 }
38 return "?" + q.Encode()
39}
40
41// listFacets builds the issue or merge request list's column from the
42// active parameters, the states the page offers, and the repository's
43// labels and open milestones. Counts are the rows' own: a label's issue
44// count on the issue list, its MR count on the MR list. A count of zero
45// is left out — it links to an empty list — unless it is the filter in
46// force, which stays so it can be cleared (#237).
47func listFacets(base url.Values, states []string, state string, labels []store.Label, ms []store.Milestone, forMRs bool) []facetGroup {
48 var st facetGroup
49 st.Title = "State"
50 for _, s := range states {
51 st.Items = append(st.Items, facetItem{Label: s, Href: facetHref(base, "state", s), Active: s == state})
52 }
53 lb := facetGroup{Title: "Labels"}
54 for _, l := range labels {
55 n := l.Issues
56 if forMRs {
57 n = l.MRs
58 }
59 active := base.Get("label") == l.Name
60 if n == 0 && !active {
61 continue
62 }
63 href := facetHref(base, "label", l.Name)
64 if active {
65 href = facetHref(base, "label", "")
66 }
67 lb.Items = append(lb.Items, facetItem{Label: l.Name, Count: n, Href: href, Active: active})
68 }
69 mg := facetGroup{Title: "Milestones"}
70 for _, m := range ms {
71 active := base.Get("milestone") == m.Title
72 if m.OpenItems == 0 && !active {
73 continue
74 }
75 href := facetHref(base, "milestone", m.Title)
76 if active {
77 href = facetHref(base, "milestone", "")
78 }
79 mg.Items = append(mg.Items, facetItem{Label: m.Title, Count: int64(m.OpenItems), Href: href, Active: active})
80 }
81 return []facetGroup{st, lb, mg}
82}