Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Add a Projects link to the global bar

cd71b776a0d2446a3b432e88289f683ad2c17fbd · Keenan Nemetz · 13d ago · parent 13cff33f

Add a Projects link to the global bar

The bar offered Activity (and Accounts to an instance admin) and nothing that
said "the repository list". The landing page was reachable only through the
emblem, which links there without saying so, and a mark is not a label: a text
destination is what makes the bar navigable.

Projects points at the landing page and marks itself current wherever the
repository list is the context — the landing page and a repository page, which is
the same global destination pageSection already assigns to "repos". The glyph is
Lucide's grid-2x2 rather than the layout-dashboard already used for the two
"Overview" subnavs, so the global bar does not reuse a tab's icon.

server/nav_test.go +48

@@ -0,0 +1,48 @@
1 package server_test
2
3 // The global bar: which destinations it offers, and which one it says you are on.
4
5 import (
6 "net/http"
7 "strings"
8 "testing"
9 )
10
11 // TestProjectsIsTheWayHome: the bar needs a text destination for the landing page.
12 // The emblem links there too, but a mark is not a label, and "Projects" is what
13 // the landing page is a list of. It marks itself current wherever the repository
14 // list is the context: the landing page and a repository page alike.
15 func TestProjectsIsTheWayHome(t *testing.T) {
16 t.Parallel()
17 f := newFixture(t)
18 f.publish(f.repo)
19
20 for _, path := range []string{"/", "/r/" + f.repo} {
21 code, body := f.get(path)
22 if code != http.StatusOK {
23 t.Fatalf("%s = %d", path, code)
24 }
25 if !strings.Contains(body, ">Projects</a>") {
26 t.Fatalf("%s has no Projects link:\n%s", path, body)
27 }
28 if !strings.Contains(body, `class="active" href="/" aria-current="page"`) {
29 t.Fatalf("%s does not mark Projects current:\n%s", path, body)
30 }
31 if !strings.Contains(body, `class="icon"`) {
32 t.Fatalf("%s renders the Projects link without an icon", path)
33 }
34 }
35
36 // Activity is a different destination, so Projects stops being current — and
37 // Activity takes over, which is what makes the bar say where you are.
38 code, body := f.get("/activity")
39 if code != http.StatusOK {
40 t.Fatalf("/activity = %d", code)
41 }
42 if strings.Contains(body, `class="active" href="/"`) {
43 t.Fatalf("/activity marks Projects current:\n%s", body)
44 }
45 if !strings.Contains(body, `class="active" href="/activity"`) {
46 t.Fatalf("/activity does not mark Activity current:\n%s", body)
47 }
48 }