vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Condense the Admin overview to one row of metric cards
9a2a270b91085170678db617a3fae6873df2fd61 · Keenan Nemetz · 4d ago · parent 0db980ee
Condense the Admin overview to one row of metric cards The overview had two card grids, five metrics followed by four account counts, and the storage and account cards repeated detail that belongs on their tabs. It is one row now: storage used, free space, users, repositories, and page views. The Users card is the active account count with the roster mix as its note (people, bots, admins, retired), so the separate account cards are gone. LFS object totals stay on the Storage tab. The queue and runner counts remain a line below the row. Refs #198 (01M6MK0NNZ2XR1D5TQKNWYT4HN).
server/admin_page_test.go +13−9
| @@ -211,7 +211,8 @@ func TestAdminAuditLogEscapesDetailAndIsNotCached(t *testing.T) { | |||
| 211 | 211 | // overview repeats counts as cards, so a test has to look past the label to say | |
| 212 | 212 | // which number belongs to it. | |
| 213 | 213 | func cardValue(body, label string) string { | |
| 214 | idx := strings.Index(body, label) | ||
| 214 | marker := `<span class="muted">` + label + `</span>` | ||
| 215 | idx := strings.Index(body, marker) | ||
| 215 | 216 | if idx < 0 { | |
| 216 | 217 | return "" | |
| 217 | 218 | } | |
| @@ -249,14 +250,17 @@ func TestAdminOverviewSummarizesAccountsAndRecentActivity(t *testing.T) { | |||
| 249 | 250 | if resp.StatusCode != http.StatusOK { | |
| 250 | 251 | t.Fatalf("GET /admin = %d:\n%s", resp.StatusCode, body) | |
| 251 | 252 | } | |
| 252 | for label, want := range map[string]string{ | ||
| 253 | "Active people": "1", | ||
| 254 | "Bots": "1", | ||
| 255 | "Instance admins": "1", | ||
| 256 | "Retired": "1", | ||
| 257 | } { | ||
| 258 | if got := cardValue(body, label); got != want { | ||
| 259 | t.Errorf("%s = %q, want %q:\n%s", label, got, want, body) | ||
| 253 | // The row is one card per metric now: active accounts, repositories, and the | ||
| 254 | // account mix as a note rather than four separate cards. | ||
| 255 | if got := cardValue(body, "Users"); got != "2" { | ||
| 256 | t.Errorf("Users = %q, want the two active accounts:\n%s", got, body) | ||
| 257 | } | ||
| 258 | if got := cardValue(body, "Repositories"); got != "1" { | ||
| 259 | t.Errorf("Repositories = %q, want 1:\n%s", got, body) | ||
| 260 | } | ||
| 261 | for _, want := range []string{"1 person", "1 bot", "1 admin", "1 retired"} { | ||
| 262 | if !strings.Contains(body, want) { | ||
| 263 | t.Fatalf("the Users card does not describe the roster with %q:\n%s", want, body) | ||
| 260 | 264 | } | |
| 261 | 265 | } | |
| 262 | 266 | // The overview shows the newest few records, not the whole log. | |