Commit 9807f90f60
Verified · cmc
internal/web/static/style.css +23
| @@ -897,6 +897,10 @@ ul.loglist .subject a { color: var(--fg); font-weight: 500; } | ||
| 897 | 897 | ul.loglist .subject a:hover { color: var(--link); } |
| 898 | 898 | ul.loglist .commitside { flex: none; display: flex; gap: var(--sp-2); align-items: center; white-space: nowrap; } |
| 899 | 899 | |
| 900 | ul.loglist.rows li { align-items: center; padding: var(--sp-2) var(--sp-4); } | |
| 901 | ul.loglist.rows .commitmain { display: flex; align-items: baseline; gap: var(--sp-3); min-width: 0; } | |
| 902 | ul.loglist.rows .meta { flex: none; color: var(--muted); font-size: var(--fs-1); white-space: nowrap; } | |
| 903 | ||
| 900 | 904 | ul.repolist { list-style: none; margin: var(--sp-3) 0 var(--sp-5); padding: 0; } |
| 901 | 905 | ul.repolist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); } |
| 902 | 906 | ul.repolist li:last-child { border-bottom: 0; } |
| @@ -909,6 +913,12 @@ ul.repolist .reponame .sep { color: var(--muted); margin: 0 2px; } | ||
| 909 | 913 | ul.repolist .desc { margin-top: 2px; } |
| 910 | 914 | ul.repolist .topics, ul.repolist .meta { margin-top: var(--sp-1); } |
| 911 | 915 | |
| 916 | ul.repolist.rows li { display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) var(--sp-4); } | |
| 917 | ul.repolist.rows .reponame { flex: none; font-size: var(--fs-2); } | |
| 918 | ul.repolist.rows .desc { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--fs-2); margin: 0; } | |
| 919 | ul.repolist.rows .topics, ul.repolist.rows .meta { flex: none; margin: 0; white-space: nowrap; } | |
| 920 | ul.repolist.rows .meta { font-size: var(--fs-1); } | |
| 921 | ||
| 912 | 922 | /* pinned repos: a compact wrap of names, no description or meta */ |
| 913 | 923 | ul.pinlist { list-style: none; margin: var(--sp-3) 0 var(--sp-5); padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); } |
| 914 | 924 | ul.pinlist li { |
| @@ -939,6 +949,15 @@ ul.issuelist .issueside { display: flex; gap: var(--sp-2); align-items: center; | ||
| 939 | 949 | ul.issuelist .title a { color: var(--fg); font-weight: 500; } |
| 940 | 950 | ul.issuelist .title a:hover { color: var(--link); } |
| 941 | 951 | |
| 952 | /* one-line rows: title, labels, then the meta pushed right. Above 64rem | |
| 953 | a list is a table, not prose (desktop layout spec). */ | |
| 954 | ul.issuelist.rows li { align-items: center; padding: var(--sp-2) var(--sp-4); } | |
| 955 | ul.issuelist.rows .issuemain { display: flex; align-items: baseline; gap: var(--sp-3); min-width: 0; } | |
| 956 | ul.issuelist.rows .title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } | |
| 957 | ul.issuelist.rows .title .chip { margin-left: var(--sp-1); } | |
| 958 | ul.issuelist.rows .meta { flex: none; color: var(--muted); font-size: var(--fs-1); white-space: nowrap; } | |
| 959 | ul.issuelist.rows .meta .repo { color: var(--fg); } | |
| 960 | ||
| 942 | 961 | ul.milestonelist { list-style: none; margin: var(--sp-3) 0; padding: 0; } |
| 943 | 962 | ul.milestonelist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); } |
| 944 | 963 | ul.milestonelist li:last-child { border-bottom: 0; } |
| @@ -1509,6 +1528,10 @@ svg.icon { vertical-align: -0.125em; } | ||
| 1509 | 1528 | /* one column, the aside after the thread: a phone shows the |
| 1510 | 1529 | description first, checks and reviewers after it (#232) */ |
| 1511 | 1530 | .withaside { grid-template-columns: 1fr; } |
| 1531 | ||
| 1532 | /* rows go back to two lines where one does not fit */ | |
| 1533 | ul.issuelist.rows .issuemain, ul.repolist.rows li, ul.loglist.rows .commitmain { display: block; } | |
| 1534 | ul.issuelist.rows .title, ul.repolist.rows .desc { white-space: normal; } | |
| 1512 | 1535 | } |
| 1513 | 1536 | |
| 1514 | 1537 | @media (max-width: 52rem) { |
internal/web/templates/dashboard.html +3 −2
| @@ -1,10 +1,11 @@ | ||
| 1 | {{define "width"}}wide{{end}} | |
| 1 | 2 | {{define "title"}}dashboard · {{.Site}}{{end}} |
| 2 | 3 | {{define "itemlist"}} |
| 3 | <ul class="issuelist"> | |
| 4 | <ul class="issuelist rows"> | |
| 4 | 5 | {{range .Items}}<li> |
| 5 | 6 | <div class="issuemain"> |
| 6 | 7 | <p class="title"><a href="/{{.RepoPath}}/{{$.Kind}}/{{.Number}}">{{.Title}}</a></p> |
| 7 | <p class="meta">{{.RepoPath}}{{if eq $.Kind "mrs"}}!{{else}}#{{end}}{{.Number}} · <a href="/{{.Author}}">{{.Author}}</a> · {{when .UpdatedAt}}{{if eq .State "source_gone"}} · <span class="chip chip-source_gone">source gone</span>{{end}}</p> | |
| 8 | <p class="meta"><span class="repo">{{.RepoPath}}{{if eq $.Kind "mrs"}}!{{else}}#{{end}}{{.Number}}</span> · <a href="/{{.Author}}">{{.Author}}</a> · {{when .UpdatedAt}}{{if eq .State "source_gone"}} · <span class="chip chip-source_gone">source gone</span>{{end}}</p> | |
| 8 | 9 | </div> |
| 9 | 10 | </li> |
| 10 | 11 | {{else}}<li class="empty">{{$.Empty}}</li>{{end}} |
internal/web/templates/explore.html +2 −1
| @@ -1,3 +1,4 @@ | ||
| 1 | {{define "width"}}wide{{end}} | |
| 1 | 2 | {{define "title"}}explore · {{.Site}}{{end}} |
| 2 | 3 | {{define "content"}} |
| 3 | 4 | <div class="headrow"> |
| @@ -8,7 +9,7 @@ | ||
| 8 | 9 | </form> |
| 9 | 10 | <span class="spacer"></span> |
| 10 | 11 | </div> |
| 11 | <ul class="repolist"> | |
| 12 | <ul class="repolist rows"> | |
| 12 | 13 | {{range .Repos}}{{template "reporow" .}} |
| 13 | 14 | {{else}}<li class="empty">no public repositories yet</li>{{end}} |
| 14 | 15 | </ul> |
internal/web/templates/globalsearch.html +1 −1
| @@ -19,7 +19,7 @@ | ||
| 19 | 19 | {{if .QueryErr}}<p class="error" role="alert">{{.QueryErr}}</p> |
| 20 | 20 | {{else if .Query}} |
| 21 | 21 | {{if .Results}} |
| 22 | <ul class="issuelist"> | |
| 22 | <ul class="issuelist rows"> | |
| 23 | 23 | {{range .Results}}<li> |
| 24 | 24 | <div class="issuemain"> |
| 25 | 25 | <p class="title"><a href="{{.Href}}">{{if .Number}}{{.Title}}{{else}}{{.Repo}}{{end}}</a></p> |
internal/web/templates/issues.html +2 −1
| @@ -1,3 +1,4 @@ | ||
| 1 | {{define "width"}}wide{{end}} | |
| 1 | 2 | {{define "title"}}issues · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}} |
| 2 | 3 | {{define "content"}} |
| 3 | 4 | <div class="listhead"> |
| @@ -16,7 +17,7 @@ | ||
| 16 | 17 | <span class="spacer"></span> |
| 17 | 18 | <p class="meta"><a href="/{{.Repo.OwnerName}}/{{.Repo.Name}}/milestones">milestones</a> · <a href="/{{.Repo.OwnerName}}/{{.Repo.Name}}/labels">labels</a>{{if .Viewer}} · <a href="/{{.Repo.OwnerName}}/{{.Repo.Name}}/issues/new">new issue</a>{{end}}</p> |
| 18 | 19 | </div> |
| 19 | <ul class="issuelist"> | |
| 20 | <ul class="issuelist rows"> | |
| 20 | 21 | {{range .Issues}}<li> |
| 21 | 22 | <div class="issuemain"> |
| 22 | 23 | <p class="title"><a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/issues/{{.Number}}">{{.Title}}</a> |
internal/web/templates/mrs.html +2 −1
| @@ -1,3 +1,4 @@ | ||
| 1 | {{define "width"}}wide{{end}} | |
| 1 | 2 | {{define "title"}}merge requests · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}} |
| 2 | 3 | {{define "content"}} |
| 3 | 4 | <div class="listhead"> |
| @@ -16,7 +17,7 @@ | ||
| 16 | 17 | {{range .Filters}}<p class="meta">{{.Key}}: {{if eq .Key "label"}}<span class="chip label" style="{{index $.LabelColors .Value}}">{{.Value}}</span>{{else}}<b>{{.Value}}</b>{{end}} <a href="{{.Clear}}">clear</a></p>{{end}} |
| 17 | 18 | </div> |
| 18 | 19 | {{if .Viewer}}<p class="meta"><a href="/{{.Repo.OwnerName}}/{{.Repo.Name}}/mrs/new">New merge request</a></p>{{end}} |
| 19 | <ul class="issuelist"> | |
| 20 | <ul class="issuelist rows"> | |
| 20 | 21 | {{range .MRs}}{{$n := .Number}}<li> |
| 21 | 22 | <div class="issuemain"> |
| 22 | 23 | <p class="title"><a href="/{{$.Repo.OwnerName}}/{{$.Repo.Name}}/mrs/{{.Number}}">{{.Title}}</a> |
internal/web/templates/notifications.html +2 −1
| @@ -1,3 +1,4 @@ | ||
| 1 | {{define "width"}}wide{{end}} | |
| 1 | 2 | {{define "title"}}notifications · {{.Site}}{{end}} |
| 2 | 3 | {{define "content"}} |
| 3 | 4 | <div class="listhead"> |
| @@ -9,7 +10,7 @@ | ||
| 9 | 10 | <span class="spacer"></span> |
| 10 | 11 | {{if .Notices}}<form method="post" action="/notifications" class="inline"><button type="submit" class="btn">Mark all read</button></form>{{end}} |
| 11 | 12 | </div> |
| 12 | <ul class="issuelist"> | |
| 13 | <ul class="issuelist rows"> | |
| 13 | 14 | {{range .Notices}}<li> |
| 14 | 15 | <div class="issuemain"> |
| 15 | 16 | <p class="title"><a href="{{.Href}}">{{.Actor}} {{.Summary}}</a></p> |
internal/web/web_test.go +1 −1
| @@ -89,7 +89,7 @@ func TestWhenNamesTheZone(t *testing.T) { | ||
| 89 | 89 | // none. The merge request page picks wide for its diff view, so it gets |
| 90 | 90 | // a per-view define instead of a fixed one. |
| 91 | 91 | func TestMainWidthClass(t *testing.T) { |
| 92 | wide := map[string]bool{"tree.html": true, "blob.html": true, "blame.html": true, "log.html": true, "commit.html": true, "compare.html": true, "builds.html": true, "build.html": true, "search.html": true, "globalsearch.html": true, "edit.html": true} | |
| 92 | wide := map[string]bool{"tree.html": true, "blob.html": true, "blame.html": true, "log.html": true, "commit.html": true, "compare.html": true, "builds.html": true, "build.html": true, "search.html": true, "globalsearch.html": true, "edit.html": true, "dashboard.html": true, "issues.html": true, "mrs.html": true, "explore.html": true, "notifications.html": true} | |
| 93 | 93 | bounded := map[string]bool{"landing.html": true, "login.html": true, "register.html": true, "registered.html": true, "new.html": true, "issuenew.html": true, "mrnew.html": true, "settings.html": true, "account.html": true, "admin.html": true, "adminusers.html": true, "snippetnew.html": true, "privacy.html": true, "404.html": true} |
| 94 | 94 | perView := map[string]string{"mr.html": `{{define "width"}}{{if eq .View "diff"}}wide{{else}}reading{{end}}{{end}}`} |
| 95 | 95 | for _, name := range Pages() { |
internal/web/widths_test.go added +36
| @@ -0,0 +1,36 @@ | ||
| 1 | package web | |
| 2 | ||
| 3 | import ( | |
| 4 | "strings" | |
| 5 | "testing" | |
| 6 | ) | |
| 7 | ||
| 8 | // List pages and the dashboard render at the container width; text pages | |
| 9 | // keep the reading cap (desktop layout spec). | |
| 10 | func TestListPagesAreWide(t *testing.T) { | |
| 11 | wide := []string{"dashboard.html", "issues.html", "mrs.html", "explore.html", "notifications.html", "globalsearch.html", "builds.html"} | |
| 12 | for _, name := range wide { | |
| 13 | src, err := templateFS.ReadFile("templates/" + name) | |
| 14 | if err != nil { | |
| 15 | t.Fatal(err) | |
| 16 | } | |
| 17 | if !strings.HasPrefix(string(src), `{{define "width"}}wide{{end}}`) { | |
| 18 | t.Errorf("%s does not declare width wide", name) | |
| 19 | } | |
| 20 | } | |
| 21 | for _, name := range []string{"issue.html", "wiki.html", "owner.html"} { | |
| 22 | src, _ := templateFS.ReadFile("templates/" + name) | |
| 23 | if strings.Contains(string(src), `{{define "width"}}wide{{end}}`) { | |
| 24 | t.Errorf("%s is a text page and must not be wide", name) | |
| 25 | } | |
| 26 | } | |
| 27 | for _, name := range []string{"issues.html", "mrs.html", "notifications.html", "globalsearch.html", "dashboard.html"} { | |
| 28 | src, _ := templateFS.ReadFile("templates/" + name) | |
| 29 | if !strings.Contains(string(src), `<ul class="issuelist rows">`) { | |
| 30 | t.Errorf("%s does not use one-line rows", name) | |
| 31 | } | |
| 32 | } | |
| 33 | if src, _ := templateFS.ReadFile("templates/explore.html"); !strings.Contains(string(src), `<ul class="repolist rows">`) { | |
| 34 | t.Error("explore.html does not use one-line rows") | |
| 35 | } | |
| 36 | } | |