internal/httpd/facets.go

1ed9fb9399b21da8e6cf45be8389792aac82d5bc
gitbay/internal/httpd/facets.go history · blame · raw

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}