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/web/admin.go +18
| @@ -8,6 +8,7 @@ package web | |||
| 8 | 8 | ||
| 9 | 9 | import ( | |
| 10 | 10 | "net/http" | |
| 11 | "strings" | ||
| 11 | 12 | "time" | |
| 12 | 13 | ) | |
| 13 | 14 | ||
| @@ -110,6 +111,23 @@ func (w *Web) accountSummary() adminAccountSummary { | |||
| 110 | 111 | return s | |
| 111 | 112 | } | |
| 112 | 113 | ||
| 114 | // UsersNote is the Users card's one-line breakdown. Zero counts are left out, | ||
| 115 | // so a clean instance reads as "3 people" rather than a row of zeros, and each | ||
| 116 | // number is spelled for its count. | ||
| 117 | func (s adminAccountSummary) UsersNote() string { | ||
| 118 | parts := []string{countLabel(s.People, "person", "people")} | ||
| 119 | if s.Bots > 0 { | ||
| 120 | parts = append(parts, countLabel(s.Bots, "bot", "bots")) | ||
| 121 | } | ||
| 122 | if s.Admins > 0 { | ||
| 123 | parts = append(parts, countLabel(s.Admins, "admin", "admins")) | ||
| 124 | } | ||
| 125 | if s.Retired > 0 { | ||
| 126 | parts = append(parts, countLabel(s.Retired, "retired", "retired")) | ||
| 127 | } | ||
| 128 | return strings.Join(parts, " · ") | ||
| 129 | } | ||
| 130 | |||
| 113 | 131 | // AdminPage is the instance-admin surface. The gate runs before anything is | |
| 114 | 132 | // read, so a non-admin cannot use the tab a request names to learn what exists. | |
| 115 | 133 | func (w *Web) AdminPage(rw http.ResponseWriter, r *http.Request) { | |