fix(web): put the repo description above content and rail
- commit
- 221e8de8c404161819df1de5ae6748dd7188af98
- author
- brice · · 2026-10-11 12:28 UTC
- parent
- c8e4042
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
9 files · +294 -292
M cmd/ermite/testdata/web/summary.html +1 -1
| @@ -75,8 +75,8 @@ | |||
| 75 | 75 | </nav> | |
| 76 | 76 | </header> | |
| 77 | 77 | <div class="work has-rail"> | |
| 78 | + | <p class="lede work-lede">A demo repository</p> | |
| 78 | 79 | <main id="main" tabindex="-1"> | |
| 79 | - | <p class="lede">A demo repository</p> | |
| 80 | 80 | <section class="card readme" aria-labelledby="readme-h"> | |
| 81 | 81 | <h2 class="card-h" id="readme-h"> | |
| 82 | 82 | <span class="ico i-file" aria-hidden="true"> | |
| @@ -75,8 +75,8 @@ | |||||
| 75 | </nav> | 75 | </nav> | ||
| 76 | </header> | 76 | </header> | ||
| 77 | <div class="work has-rail"> | 77 | <div class="work has-rail"> | ||
| 78 | + | <p class="lede work-lede">A demo repository</p> | |||
| 78 | <main id="main" tabindex="-1"> | 79 | <main id="main" tabindex="-1"> | ||
| 79 | - | <p class="lede">A demo repository</p> | |||
| 80 | <section class="card readme" aria-labelledby="readme-h"> | 80 | <section class="card readme" aria-labelledby="readme-h"> | ||
| 81 | <h2 class="card-h" id="readme-h"> | 81 | <h2 class="card-h" id="readme-h"> | ||
| 82 | <span class="ico i-file" aria-hidden="true"> | 82 | <span class="ico i-file" aria-hidden="true"> | ||
M internal/adapters/web/assets.go +1 -1
| @@ -4,9 +4,9 @@ package web | |||
| 4 | 4 | ||
| 5 | 5 | import ( | |
| 6 | 6 | "crypto/sha256" | |
| 7 | - | "errors" | |
| 8 | 7 | "embed" | |
| 9 | 8 | "encoding/hex" | |
| 9 | + | "errors" | |
| 10 | 10 | "io/fs" | |
| 11 | 11 | "net/http" | |
| 12 | 12 | "path" | |
| @@ -4,9 +4,9 @@ package web | |||||
| 4 | 4 | ||||
| 5 | import ( | 5 | import ( | ||
| 6 | "crypto/sha256" | 6 | "crypto/sha256" | ||
| 7 | - | "errors" | |||
| 8 | "embed" | 7 | "embed" | ||
| 9 | "encoding/hex" | 8 | "encoding/hex" | ||
| 9 | + | "errors" | |||
| 10 | "io/fs" | 10 | "io/fs" | ||
| 11 | "net/http" | 11 | "net/http" | ||
| 12 | "path" | 12 | "path" | ||
M internal/adapters/web/pages.templ +0 -3
| @@ -48,9 +48,6 @@ templ Home(l Layout, p HomePage) { | |||
| 48 | 48 | // column at the reading measure; what one acts on sits in the rail. | |
| 49 | 49 | templ Summary(l Layout, p SummaryPage) { | |
| 50 | 50 | @Shell(l, summaryRail(p)) { | |
| 51 | - | if p.Desc != "" { | |
| 52 | - | <p class="lede">{ p.Desc }</p> | |
| 53 | - | } | |
| 54 | 51 | if p.Readme != nil { | |
| 55 | 52 | @ReadmeCard(*p.Readme) | |
| 56 | 53 | } | |
| @@ -48,9 +48,6 @@ templ Home(l Layout, p HomePage) { | |||||
| 48 | // column at the reading measure; what one acts on sits in the rail. | 48 | // column at the reading measure; what one acts on sits in the rail. | ||
| 49 | templ Summary(l Layout, p SummaryPage) { | 49 | templ Summary(l Layout, p SummaryPage) { | ||
| 50 | @Shell(l, summaryRail(p)) { | 50 | @Shell(l, summaryRail(p)) { | ||
| 51 | - | if p.Desc != "" { | |||
| 52 | - | <p class="lede">{ p.Desc }</p> | |||
| 53 | - | } | |||
| 54 | if p.Readme != nil { | 51 | if p.Readme != nil { | ||
| 55 | @ReadmeCard(*p.Readme) | 52 | @ReadmeCard(*p.Readme) | ||
| 56 | } | 53 | } | ||
M internal/adapters/web/pages_templ.go +157 -180 generated file: collapsed
M internal/adapters/web/shell.templ +3 -0
| @@ -25,6 +25,9 @@ templ Shell(l Layout, rail templ.Component) { | |||
| 25 | 25 | <a class="skip" href="#main">skip to content</a> | |
| 26 | 26 | @Header(l) | |
| 27 | 27 | <div class={ "work", templ.KV("has-rail", l.HasRail && rail != nil) }> | |
| 28 | + | if l.Lede != "" { | |
| 29 | + | <p class="lede work-lede">{ l.Lede }</p> | |
| 30 | + | } | |
| 28 | 31 | <main id="main" tabindex="-1"> | |
| 29 | 32 | { children... } | |
| 30 | 33 | </main> | |
| @@ -25,6 +25,9 @@ templ Shell(l Layout, rail templ.Component) { | |||||
| 25 | <a class="skip" href="#main">skip to content</a> | 25 | <a class="skip" href="#main">skip to content</a> | ||
| 26 | @Header(l) | 26 | @Header(l) | ||
| 27 | <div class={ "work", templ.KV("has-rail", l.HasRail && rail != nil) }> | 27 | <div class={ "work", templ.KV("has-rail", l.HasRail && rail != nil) }> | ||
| 28 | + | if l.Lede != "" { | |||
| 29 | + | <p class="lede work-lede">{ l.Lede }</p> | |||
| 30 | + | } | |||
| 28 | <main id="main" tabindex="-1"> | 31 | <main id="main" tabindex="-1"> | ||
| 29 | { children... } | 32 | { children... } | ||
| 30 | </main> | 33 | </main> | ||
M internal/adapters/web/shell_templ.go +128 -105 generated file: collapsed
M internal/adapters/web/static/css/20-shell.css +1 -0
| @@ -108,6 +108,7 @@ | |||
| 108 | 108 | } | |
| 109 | 109 | .work.has-rail { grid-template-columns: minmax(0, 1fr) var(--rail); } | |
| 110 | 110 | .rail { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; } | |
| 111 | + | .work-lede { grid-column: 1 / -1; margin-bottom: calc(-1 * var(--s2)); } | |
| 111 | 112 | main > * + * { margin-top: var(--s4); } | |
| 112 | 113 | ||
| 113 | 114 | /* blocks: a surface with a header; rail sections are blocks too */ | |
| @@ -108,6 +108,7 @@ | |||||
| 108 | } | 108 | } | ||
| 109 | .work.has-rail { grid-template-columns: minmax(0, 1fr) var(--rail); } | 109 | .work.has-rail { grid-template-columns: minmax(0, 1fr) var(--rail); } | ||
| 110 | .rail { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; } | 110 | .rail { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; } | ||
| 111 | + | .work-lede { grid-column: 1 / -1; margin-bottom: calc(-1 * var(--s2)); } | |||
| 111 | main > * + * { margin-top: var(--s4); } | 112 | main > * + * { margin-top: var(--s4); } | ||
| 112 | 113 | ||||
| 113 | /* blocks: a surface with a header; rail sections are blocks too */ | 114 | /* blocks: a surface with a header; rail sections are blocks too */ | ||
M internal/adapters/web/summary.go +1 -1
| @@ -44,7 +44,6 @@ func (s *Server) summary(ctx context.Context, r *http.Request) (templ.Component, | |||
| 44 | 44 | now := s.cfg.Now() | |
| 45 | 45 | ||
| 46 | 46 | p := SummaryPage{ | |
| 47 | - | Desc: d.repo.GetDescription(), | |
| 48 | 47 | AllHref: repoHref(d.name(), "commits", ref), | |
| 49 | 48 | Clone: Clone{ID: "clone-" + d.name(), Lines: []string{"git clone " + s.cloneURL(d.name())}}, | |
| 50 | 49 | } | |
| @@ -74,6 +73,7 @@ func (s *Server) summary(ctx context.Context, r *http.Request) (templ.Component, | |||
| 74 | 73 | l.Title = d.name() + " · " + s.instance | |
| 75 | 74 | l.Live, l.LiveURL = true, liveURL("repo:"+d.name(), "view=summary") | |
| 76 | 75 | l.HasRail = true | |
| 76 | + | l.Lede = d.repo.GetDescription() | |
| 77 | 77 | return Summary(l, p), http.StatusOK, nil | |
| 78 | 78 | } | |
| 79 | 79 | ||
| @@ -44,7 +44,6 @@ func (s *Server) summary(ctx context.Context, r *http.Request) (templ.Component, | |||||
| 44 | now := s.cfg.Now() | 44 | now := s.cfg.Now() | ||
| 45 | 45 | ||||
| 46 | p := SummaryPage{ | 46 | p := SummaryPage{ | ||
| 47 | - | Desc: d.repo.GetDescription(), | |||
| 48 | AllHref: repoHref(d.name(), "commits", ref), | 47 | AllHref: repoHref(d.name(), "commits", ref), | ||
| 49 | Clone: Clone{ID: "clone-" + d.name(), Lines: []string{"git clone " + s.cloneURL(d.name())}}, | 48 | Clone: Clone{ID: "clone-" + d.name(), Lines: []string{"git clone " + s.cloneURL(d.name())}}, | ||
| 50 | } | 49 | } | ||
| @@ -74,6 +73,7 @@ func (s *Server) summary(ctx context.Context, r *http.Request) (templ.Component, | |||||
| 74 | l.Title = d.name() + " · " + s.instance | 73 | l.Title = d.name() + " · " + s.instance | ||
| 75 | l.Live, l.LiveURL = true, liveURL("repo:"+d.name(), "view=summary") | 74 | l.Live, l.LiveURL = true, liveURL("repo:"+d.name(), "view=summary") | ||
| 76 | l.HasRail = true | 75 | l.HasRail = true | ||
| 76 | + | l.Lede = d.repo.GetDescription() | |||
| 77 | return Summary(l, p), http.StatusOK, nil | 77 | return Summary(l, p), http.StatusOK, nil | ||
| 78 | } | 78 | } | ||
| 79 | 79 | ||||
M internal/adapters/web/view.go +2 -1
| @@ -50,6 +50,8 @@ type Layout struct { | |||
| 50 | 50 | Tags []RefItem | |
| 51 | 51 | Cmd []CmdItem | |
| 52 | 52 | HasRail bool | |
| 53 | + | // Lede is a line above the content and the rail, so both start level. | |
| 54 | + | Lede string | |
| 53 | 55 | // Live connects the page to the event stream (/-/events). | |
| 54 | 56 | Live bool | |
| 55 | 57 | // LiveURL is the stream the page follows, with its query. | |
| @@ -133,7 +135,6 @@ type CommitRow struct { | |||
| 133 | 135 | ||
| 134 | 136 | // SummaryPage is the repository summary. | |
| 135 | 137 | type SummaryPage struct { | |
| 136 | - | Desc string | |
| 137 | 138 | Facts []Fact | |
| 138 | 139 | Clone Clone | |
| 139 | 140 | Recent []CommitRow | |
| @@ -50,6 +50,8 @@ type Layout struct { | |||||
| 50 | Tags []RefItem | 50 | Tags []RefItem | ||
| 51 | Cmd []CmdItem | 51 | Cmd []CmdItem | ||
| 52 | HasRail bool | 52 | HasRail bool | ||
| 53 | + | // Lede is a line above the content and the rail, so both start level. | |||
| 54 | + | Lede string | |||
| 53 | // Live connects the page to the event stream (/-/events). | 55 | // Live connects the page to the event stream (/-/events). | ||
| 54 | Live bool | 56 | Live bool | ||
| 55 | // LiveURL is the stream the page follows, with its query. | 57 | // LiveURL is the stream the page follows, with its query. | ||
| @@ -133,7 +135,6 @@ type CommitRow struct { | |||||
| 133 | 135 | ||||
| 134 | // SummaryPage is the repository summary. | 136 | // SummaryPage is the repository summary. | ||
| 135 | type SummaryPage struct { | 137 | type SummaryPage struct { | ||
| 136 | - | Desc string | |||
| 137 | Facts []Fact | 138 | Facts []Fact | ||
| 138 | Clone Clone | 139 | Clone Clone | ||
| 139 | Recent []CommitRow | 140 | Recent []CommitRow | ||