diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-02-22 17:00:10 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-02-22 17:52:26 +0100 |
| commit | 00f8fc943e4837459d194201c6d5d7f5b95e9f67 (patch) | |
| tree | e3c09815857ca9049800a9a4d0be0e43a964c529 | |
| parent | 6b9e84f9440313dcd09e408d09d3440f666db8ff (diff) | |
dashboard: filter by no subsystems
Count the number of bugs without any subsystem and let users filter bugs
by this criteria.
| -rw-r--r-- | dashboard/app/cache.go | 8 | ||||
| -rw-r--r-- | dashboard/app/main.go | 18 | ||||
| -rw-r--r-- | dashboard/app/main_test.go | 6 | ||||
| -rw-r--r-- | dashboard/app/subsystems.html | 6 | ||||
| -rw-r--r-- | dashboard/app/templates.html | 3 |
5 files changed, 37 insertions, 4 deletions
diff --git a/dashboard/app/cache.go b/dashboard/app/cache.go index 177d4750f..2c8ca6376 100644 --- a/dashboard/app/cache.go +++ b/dashboard/app/cache.go @@ -15,8 +15,9 @@ import ( ) type Cached struct { - Total CachedBugStats - Subsystems map[string]CachedBugStats + Total CachedBugStats + Subsystems map[string]CachedBugStats + NoSubsystem CachedBugStats } type CachedBugStats struct { @@ -76,6 +77,9 @@ func buildAndStoreCached(c context.Context, bugs []*Bug, ns string, accessLevel stats.Record(bug) v.Subsystems[subsystem.Name] = stats } + if len(bug.Tags.Subsystems) == 0 { + v.NoSubsystem.Record(bug) + } } item := &memcache.Item{ Key: cacheKey(ns, accessLevel), diff --git a/dashboard/app/main.go b/dashboard/app/main.go index 55574c4c0..ad503c0ef 100644 --- a/dashboard/app/main.go +++ b/dashboard/app/main.go @@ -351,11 +351,13 @@ type userBugFilter struct { Manager string // show bugs that happened on the manager OnlyManager string // show bugs that happened ONLY on the manager Subsystem string // only show bugs belonging to the subsystem + NoSubsystem bool } func MakeBugFilter(r *http.Request) *userBugFilter { return &userBugFilter{ Subsystem: r.FormValue("subsystem"), + NoSubsystem: r.FormValue("no_subsystem") != "", Manager: r.FormValue("manager"), OnlyManager: r.FormValue("only_manager"), } @@ -386,6 +388,9 @@ func (filter *userBugFilter) MatchBug(bug *Bug) bool { if filter.Manager != "" && !stringInList(bug.HappenedOn, filter.Manager) { return false } + if filter.NoSubsystem && len(bug.Tags.Subsystems) > 0 { + return false + } if filter.Subsystem != "" && !bug.hasSubsystem(filter.Subsystem) { return false } @@ -396,7 +401,7 @@ func (filter *userBugFilter) Any() bool { if filter == nil { return false } - return filter.Subsystem != "" || filter.OnlyManager != "" || filter.Manager != "" + return filter.Subsystem != "" || filter.OnlyManager != "" || filter.Manager != "" || filter.NoSubsystem } // handleMain serves main page. @@ -862,6 +867,17 @@ func handleSubsystemsList(c context.Context, w http.ResponseWriter, r *http.Requ } list = append(list, record) } + list = append(list, &uiSubsystem{ + Name: "", + Open: uiSubsystemStats{ + Count: cached.NoSubsystem.Open, + Link: html.AmendURL("/"+hdr.Namespace, "no_subsystem", "true"), + }, + Fixed: uiSubsystemStats{ + Count: cached.NoSubsystem.Open, + Link: html.AmendURL("/"+hdr.Namespace+"/fixed", "no_subsystem", "true"), + }, + }) sort.Slice(list, func(i, j int) bool { return list[i].Name < list[j].Name }) return serveTemplate(w, "subsystems.html", &uiSubsystemsPage{ Header: hdr, diff --git a/dashboard/app/main_test.go b/dashboard/app/main_test.go index fe9410da3..3a07f5040 100644 --- a/dashboard/app/main_test.go +++ b/dashboard/app/main_test.go @@ -169,6 +169,7 @@ func TestMainBugFilters(t *testing.T) { client.UploadBuild(build1) crash1 := testCrash(build1, 1) + crash1.Title = "my-crash-title" client.ReportCrash(crash1) client.pollBugs(1) @@ -182,6 +183,11 @@ func TestMainBugFilters(t *testing.T) { c.expectOK(err) assert.NotContains(t, string(reply), build1.Manager) // managers are hidden assert.Contains(t, string(reply), "Applied filters") // we're seeing a prompt to disable the filter + assert.NotContains(t, string(reply), crash1.Title) // the bug does not belong to the subsystem + + reply, err = c.AuthGET(AccessAdmin, "/test1?no_subsystem=true") + c.expectOK(err) + assert.Contains(t, string(reply), crash1.Title) // the bug has no subsystems } func TestSubsystemsList(t *testing.T) { diff --git a/dashboard/app/subsystems.html b/dashboard/app/subsystems.html index b6f9bbd71..2b1fe0f57 100644 --- a/dashboard/app/subsystems.html +++ b/dashboard/app/subsystems.html @@ -28,7 +28,11 @@ The list of polled trees. </tr> {{range $item := .List}} <tr> - <td>{{link $item.Open.Link $item.Name}}</td> + {{if $item.Name}} + <td>{{link $item.Open.Link $item.Name}}</td> + {{else}} + <td><b>{{link $item.Open.Link "no subsystem"}}</b></td> + {{end}} <td>{{$item.Lists}}</td> <td>{{link $item.Open.Link (printf "%d" $item.Open.Count)}}</td> <td>{{link $item.Fixed.Link (printf "%d" $item.Fixed.Count)}}</td> diff --git a/dashboard/app/templates.html b/dashboard/app/templates.html index 0a2c9301a..52b8e4ea6 100644 --- a/dashboard/app/templates.html +++ b/dashboard/app/templates.html @@ -102,6 +102,9 @@ Use of this source code is governed by Apache 2 LICENSE that can be found in the {{if .Filter.Subsystem}} Subsystem={{.Filter.Subsystem}} ({{link (call .DropURL "subsystem") "drop"}}) {{end}} + {{if .Filter.NoSubsystem}} + NoSubsystem={{.Filter.NoSubsystem}} ({{link (call .DropURL "no_subsystem") "drop"}}) + {{end}} <br> {{end}} {{end}} |
