#30 feat(web): release card, latest release in About, g-sequence shortcuts
M README.md +1 -0
| @@ -139,6 +139,7 @@ Give the agent the [`skills/ermite`](skills/ermite/SKILL.md) skill so it knows t | |||
| 139 | 139 | - [Issues](docs/issues.md) | |
| 140 | 140 | - [Commit signatures](docs/commit-signatures.md): SSH and OpenPGP badges, trusted keys | |
| 141 | 141 | - [Web sign-in](docs/web-sign-in.md): passkeys and one-time links | |
| 142 | + | - [Keyboard shortcuts](docs/keyboard-shortcuts.md): web section navigation and page actions | |
| 142 | 143 | - [CI](docs/ci.md): runners, trust, concurrency, reusable workflows | |
| 143 | 144 | - [CI events](docs/ci-events.md) | |
| 144 | 145 | - [OIDC](docs/ci-oidc.md) | |
| @@ -139,6 +139,7 @@ Give the agent the [`skills/ermite`](skills/ermite/SKILL.md) skill so it knows t | |||||
| 139 | - [Issues](docs/issues.md) | 139 | - [Issues](docs/issues.md) | ||
| 140 | - [Commit signatures](docs/commit-signatures.md): SSH and OpenPGP badges, trusted keys | 140 | - [Commit signatures](docs/commit-signatures.md): SSH and OpenPGP badges, trusted keys | ||
| 141 | - [Web sign-in](docs/web-sign-in.md): passkeys and one-time links | 141 | - [Web sign-in](docs/web-sign-in.md): passkeys and one-time links | ||
| 142 | + | - [Keyboard shortcuts](docs/keyboard-shortcuts.md): web section navigation and page actions | |||
| 142 | - [CI](docs/ci.md): runners, trust, concurrency, reusable workflows | 143 | - [CI](docs/ci.md): runners, trust, concurrency, reusable workflows | ||
| 143 | - [CI events](docs/ci-events.md) | 144 | - [CI events](docs/ci-events.md) | ||
| 144 | - [OIDC](docs/ci-oidc.md) | 145 | - [OIDC](docs/ci-oidc.md) | ||
M docs/issues.md +1 -1
| @@ -50,7 +50,7 @@ Limits: the 100 most recent commits of the merge request, 16 KiB of each text, 1 | |||
| 50 | 50 | ||
| 51 | 51 | The signed-in owner has an Inbox at `/-/inbox`, reached from the **Inbox** button at the top left of the home page, which shows the number of open items. It lists the open merge requests and the open issues of every repository, most recently updated first. The counters at the top (`N merge requests · M issues`) always count everything; `?repo=<name>` restricts the two lists to one repository, and the repository links under the counters set it. Repositories with issues off contribute no issues. | |
| 52 | 52 | ||
| 53 | - | The **Running** section, after **Awaiting moderation**, lists queued and in-progress CI runs newest first, with links to each run, its repository, ref, and start time. The `N running` counter counts every repository; the repository filter also applies to this section. **Shift+I** (`I`) opens the inbox from any page for the signed-in owner, unless single-key shortcuts are off; lowercase `i` still opens the issues tab. | |
| 53 | + | The **Running** section, after **Awaiting moderation**, lists queued and in-progress CI runs newest first, with links to each run, its repository, ref, and start time. The `N running` counter counts every repository; the repository filter also applies to this section. **Shift+I** (`I`) opens the inbox from any page for the signed-in owner, unless single-key shortcuts are off; `g i` opens the issues tab. | |
| 54 | 54 | ||
| 55 | 55 | The page updates live: run status changes, merge request and issue events of any repository refresh the counters and the lists. Anyone who is not the signed-in owner, including a token, gets the same 404 as for an unknown page, and the same answer for the `owner` event stream it follows. | |
| 56 | 56 | ||
| @@ -50,7 +50,7 @@ Limits: the 100 most recent commits of the merge request, 16 KiB of each text, 1 | |||||
| 50 | 50 | ||||
| 51 | The signed-in owner has an Inbox at `/-/inbox`, reached from the **Inbox** button at the top left of the home page, which shows the number of open items. It lists the open merge requests and the open issues of every repository, most recently updated first. The counters at the top (`N merge requests · M issues`) always count everything; `?repo=<name>` restricts the two lists to one repository, and the repository links under the counters set it. Repositories with issues off contribute no issues. | 51 | The signed-in owner has an Inbox at `/-/inbox`, reached from the **Inbox** button at the top left of the home page, which shows the number of open items. It lists the open merge requests and the open issues of every repository, most recently updated first. The counters at the top (`N merge requests · M issues`) always count everything; `?repo=<name>` restricts the two lists to one repository, and the repository links under the counters set it. Repositories with issues off contribute no issues. | ||
| 52 | 52 | ||||
| 53 | - | The **Running** section, after **Awaiting moderation**, lists queued and in-progress CI runs newest first, with links to each run, its repository, ref, and start time. The `N running` counter counts every repository; the repository filter also applies to this section. **Shift+I** (`I`) opens the inbox from any page for the signed-in owner, unless single-key shortcuts are off; lowercase `i` still opens the issues tab. | 53 | + | The **Running** section, after **Awaiting moderation**, lists queued and in-progress CI runs newest first, with links to each run, its repository, ref, and start time. The `N running` counter counts every repository; the repository filter also applies to this section. **Shift+I** (`I`) opens the inbox from any page for the signed-in owner, unless single-key shortcuts are off; `g i` opens the issues tab. |
| 54 | 54 | ||||
| 55 | The page updates live: run status changes, merge request and issue events of any repository refresh the counters and the lists. Anyone who is not the signed-in owner, including a token, gets the same 404 as for an unknown page, and the same answer for the `owner` event stream it follows. | 55 | The page updates live: run status changes, merge request and issue events of any repository refresh the counters and the lists. Anyone who is not the signed-in owner, including a token, gets the same 404 as for an unknown page, and the same answer for the `owner` event stream it follows. | ||
| 56 | 56 | ||||
A docs/keyboard-shortcuts.md +30 -0
| @@ -0,0 +1,30 @@ | |||
| 1 | + | # Web keyboard shortcuts | |
| 2 | + | ||
| 3 | + | Press `?` for the complete, page-specific list. Shortcuts do not run while typing | |
| 4 | + | in a field. Section navigation uses two successive keys, not a chord: | |
| 5 | + | ||
| 6 | + | | Keys | Destination | | |
| 7 | + | | --- | --- | | |
| 8 | + | | `g s` | Summary | | |
| 9 | + | | `g f` | Files | | |
| 10 | + | | `g c` | Commits | | |
| 11 | + | | `g b` | Branches & tags | | |
| 12 | + | | `g m` | Merge requests | | |
| 13 | + | | `g i` | Issues | | |
| 14 | + | | `g r` | Releases | | |
| 15 | + | | `g a` | Actions (when CI is enabled) | | |
| 16 | + | | `g h` | Home | | |
| 17 | + | | `g g` | Top / first row | | |
| 18 | + | | `G` (Shift+g) | Bottom / last row | | |
| 19 | + | ||
| 20 | + | There is no `g t` alias, and `s`, `t`, `c`, `r`, `m`, and `i` alone do | |
| 21 | + | not navigate sections. `b` still opens the branch/tag switcher; `f`, `:`, | |
| 22 | + | and Ctrl+K (Cmd+K on macOS) open the command palette. | |
| 23 | + | ||
| 24 | + | On merge requests, `l` focuses the files side panel; `g f` always navigates | |
| 25 | + | to the repository Files section. `h` returns to the content. Uppercase `M` | |
| 26 | + | opens the merge menu, `R` marks the head read, `E` expands every diff file, | |
| 27 | + | and `I` opens the signed-in owner's inbox. | |
| 28 | + | ||
| 29 | + | The help dialog can turn off character shortcuts, including `g` sequences | |
| 30 | + | and shifted letters. Ctrl+K / Cmd+K and Escape remain available. | |
| @@ -0,0 +1,30 @@ | |||||
| 1 | + | # Web keyboard shortcuts | |||
| 2 | + | ||||
| 3 | + | Press `?` for the complete, page-specific list. Shortcuts do not run while typing | |||
| 4 | + | in a field. Section navigation uses two successive keys, not a chord: | |||
| 5 | + | ||||
| 6 | + | | Keys | Destination | | |||
| 7 | + | | --- | --- | | |||
| 8 | + | | `g s` | Summary | | |||
| 9 | + | | `g f` | Files | | |||
| 10 | + | | `g c` | Commits | | |||
| 11 | + | | `g b` | Branches & tags | | |||
| 12 | + | | `g m` | Merge requests | | |||
| 13 | + | | `g i` | Issues | | |||
| 14 | + | | `g r` | Releases | | |||
| 15 | + | | `g a` | Actions (when CI is enabled) | | |||
| 16 | + | | `g h` | Home | | |||
| 17 | + | | `g g` | Top / first row | | |||
| 18 | + | | `G` (Shift+g) | Bottom / last row | | |||
| 19 | + | ||||
| 20 | + | There is no `g t` alias, and `s`, `t`, `c`, `r`, `m`, and `i` alone do | |||
| 21 | + | not navigate sections. `b` still opens the branch/tag switcher; `f`, `:`, | |||
| 22 | + | and Ctrl+K (Cmd+K on macOS) open the command palette. | |||
| 23 | + | ||||
| 24 | + | On merge requests, `l` focuses the files side panel; `g f` always navigates | |||
| 25 | + | to the repository Files section. `h` returns to the content. Uppercase `M` | |||
| 26 | + | opens the merge menu, `R` marks the head read, `E` expands every diff file, | |||
| 27 | + | and `I` opens the signed-in owner's inbox. | |||
| 28 | + | ||||
| 29 | + | The help dialog can turn off character shortcuts, including `g` sequences | |||
| 30 | + | and shifted letters. Ctrl+K / Cmd+K and Escape remain available. | |||
M docs/merge-requests.md +1 -1
| @@ -142,7 +142,7 @@ the diff opens the Checks panel and continues to update live. Commit totals use | |||
| 142 | 142 | `N+` when the branch list is capped: the reader's existing count operation counts all reachable | |
| 143 | 143 | ancestors, not the source-minus-target range. | |
| 144 | 144 | ||
| 145 | - | The rail keeps Files (including its `g f` shortcut) and Verdicts. Merge settings | |
| 145 | + | The rail keeps Files (including its `l` shortcut) and Verdicts. Merge settings | |
| 146 | 146 | are read-only information in the More (⋯) menu, available to every viewer. | |
| 147 | 147 | Signing-key information is also there when a merge box offers signed modes; | |
| 148 | 148 | merge actions remain restricted to their existing permissions. | |
| @@ -142,7 +142,7 @@ the diff opens the Checks panel and continues to update live. Commit totals use | |||||
| 142 | `N+` when the branch list is capped: the reader's existing count operation counts all reachable | 142 | `N+` when the branch list is capped: the reader's existing count operation counts all reachable | ||
| 143 | ancestors, not the source-minus-target range. | 143 | ancestors, not the source-minus-target range. | ||
| 144 | 144 | ||||
| 145 | - | The rail keeps Files (including its `g f` shortcut) and Verdicts. Merge settings | 145 | + | The rail keeps Files (including its `l` shortcut) and Verdicts. Merge settings |
| 146 | are read-only information in the More (⋯) menu, available to every viewer. | 146 | are read-only information in the More (⋯) menu, available to every viewer. | ||
| 147 | Signing-key information is also there when a merge box offers signed modes; | 147 | Signing-key information is also there when a merge box offers signed modes; | ||
| 148 | merge actions remain restricted to their existing permissions. | 148 | merge actions remain restricted to their existing permissions. | ||
M internal/adapters/kvstore/issues_test.go +1 -1
| @@ -364,7 +364,7 @@ func TestSchemaNewerThanThisBuildStopsIssuesData(t *testing.T) { | |||
| 364 | 364 | putRaw(t, dir, "meta/schema", mustProto(t, &storagepb.SchemaVersion{Version: kvstore.SchemaVersion + 1})) | |
| 365 | 365 | _, err := kvstore.Open(ctx, dir) | |
| 366 | 366 | require.ErrorIs(t, err, kvstore.ErrSchemaTooNew) | |
| 367 | - | assert.Equal(t, uint32(6), uint32(kvstore.SchemaVersion)) | |
| 367 | + | assert.Equal(t, uint32(7), uint32(kvstore.SchemaVersion)) | |
| 368 | 368 | } | |
| 369 | 369 | ||
| 370 | 370 | // A reopen racing the delete of the repository either lands before the delete | |
| @@ -364,7 +364,7 @@ func TestSchemaNewerThanThisBuildStopsIssuesData(t *testing.T) { | |||||
| 364 | putRaw(t, dir, "meta/schema", mustProto(t, &storagepb.SchemaVersion{Version: kvstore.SchemaVersion + 1})) | 364 | putRaw(t, dir, "meta/schema", mustProto(t, &storagepb.SchemaVersion{Version: kvstore.SchemaVersion + 1})) | ||
| 365 | _, err := kvstore.Open(ctx, dir) | 365 | _, err := kvstore.Open(ctx, dir) | ||
| 366 | require.ErrorIs(t, err, kvstore.ErrSchemaTooNew) | 366 | require.ErrorIs(t, err, kvstore.ErrSchemaTooNew) | ||
| 367 | - | assert.Equal(t, uint32(6), uint32(kvstore.SchemaVersion)) | 367 | + | assert.Equal(t, uint32(7), uint32(kvstore.SchemaVersion)) |
| 368 | } | 368 | } | ||
| 369 | 369 | ||||
| 370 | // A reopen racing the delete of the repository either lands before the delete | 370 | // A reopen racing the delete of the repository either lands before the delete | ||
M internal/adapters/kvstore/releases.go +28 -2
| @@ -36,7 +36,26 @@ func relNamePrefix(repo domain.RepoName, id int64) string { | |||
| 36 | 36 | func relNameKey(a domain.ReleaseAsset) []byte { | |
| 37 | 37 | return []byte(relNamePrefix(a.Repo, a.ReleaseID) + a.Name) | |
| 38 | 38 | } | |
| 39 | - | func relUseKey(repo domain.RepoName) []byte { return []byte("reluse/" + repo.String()) } | |
| 39 | + | func relLatestKey(repo domain.RepoName) []byte { return []byte("rellatest/" + repo.String()) } | |
| 40 | + | func relUseKey(repo domain.RepoName) []byte { return []byte("reluse/" + repo.String()) } | |
| 41 | + | ||
| 42 | + | // GetLatestRelease resolves the index and release from the same snapshot. | |
| 43 | + | func (c *Releases) GetLatestRelease(ctx context.Context, repo domain.RepoName) (domain.Release, error) { | |
| 44 | + | snap := c.db.Snapshot(ctx) | |
| 45 | + | item, ok := snap.Get(ctx, relLatestKey(repo)) | |
| 46 | + | if !ok { | |
| 47 | + | return domain.Release{}, domain.ErrNotFound | |
| 48 | + | } | |
| 49 | + | id, err := strconv.ParseInt(string(item.Value), 10, 64) | |
| 50 | + | if err != nil { | |
| 51 | + | return domain.Release{}, err | |
| 52 | + | } | |
| 53 | + | item, ok = snap.Get(ctx, relKey(repo, id)) | |
| 54 | + | if !ok { | |
| 55 | + | return domain.Release{}, domain.ErrNotFound | |
| 56 | + | } | |
| 57 | + | return decodeRelease(item) | |
| 58 | + | } | |
| 40 | 59 | func encodeRelease(r domain.Release) []byte { | |
| 41 | 60 | return mustMarshal(&storagepb.Release{ | |
| 42 | 61 | Id: r.ID, | |
| @@ -285,6 +304,13 @@ func (c *Releases) ApplyReleases(ctx context.Context, w ports.ReleaseWrite) erro | |||
| 285 | 304 | b.RequireVersion(relUseKey(w.Repo), w.UsageVersion) | |
| 286 | 305 | } | |
| 287 | 306 | b.Put(relUseKey(w.Repo), mustMarshal(&storagepb.ReleaseUsage{Used: w.Used})) | |
| 307 | + | if w.SetLatest { | |
| 308 | + | if w.LatestID > 0 { | |
| 309 | + | b.Put(relLatestKey(w.Repo), []byte(strconv.FormatInt(w.LatestID, 10))) | |
| 310 | + | } else { | |
| 311 | + | b.Delete(relLatestKey(w.Repo)) | |
| 312 | + | } | |
| 313 | + | } | |
| 288 | 314 | snap := c.db.Snapshot(ctx) | |
| 289 | 315 | for _, r := range w.DeleteReleases { | |
| 290 | 316 | if r.Repo != w.Repo || r.Version == 0 { | |
| @@ -388,7 +414,7 @@ func (c *Releases) ApplyReleases(ctx context.Context, w ports.ReleaseWrite) erro | |||
| 388 | 414 | ||
| 389 | 415 | // releaseKeys collects all repository-owned release keys, including global indexes. | |
| 390 | 416 | func releaseKeys(ctx context.Context, snap *kv.Snapshot, repo domain.RepoName) [][]byte { | |
| 391 | - | keys := [][]byte{relUseKey(repo)} | |
| 417 | + | keys := [][]byte{relUseKey(repo), relLatestKey(repo)} | |
| 392 | 418 | for _, prefix := range []string{"rel/", "reltag/", "relassets/"} { | |
| 393 | 419 | for key, item := range snap.Prefix(ctx, []byte(prefix+repo.String()+"/")) { | |
| 394 | 420 | keys = append(keys, slices.Clone(key)) | |
| @@ -36,7 +36,26 @@ func relNamePrefix(repo domain.RepoName, id int64) string { | |||||
| 36 | func relNameKey(a domain.ReleaseAsset) []byte { | 36 | func relNameKey(a domain.ReleaseAsset) []byte { | ||
| 37 | return []byte(relNamePrefix(a.Repo, a.ReleaseID) + a.Name) | 37 | return []byte(relNamePrefix(a.Repo, a.ReleaseID) + a.Name) | ||
| 38 | } | 38 | } | ||
| 39 | - | func relUseKey(repo domain.RepoName) []byte { return []byte("reluse/" + repo.String()) } | 39 | + | func relLatestKey(repo domain.RepoName) []byte { return []byte("rellatest/" + repo.String()) } |
| 40 | + | func relUseKey(repo domain.RepoName) []byte { return []byte("reluse/" + repo.String()) } | |||
| 41 | + | ||||
| 42 | + | // GetLatestRelease resolves the index and release from the same snapshot. | |||
| 43 | + | func (c *Releases) GetLatestRelease(ctx context.Context, repo domain.RepoName) (domain.Release, error) { | |||
| 44 | + | snap := c.db.Snapshot(ctx) | |||
| 45 | + | item, ok := snap.Get(ctx, relLatestKey(repo)) | |||
| 46 | + | if !ok { | |||
| 47 | + | return domain.Release{}, domain.ErrNotFound | |||
| 48 | + | } | |||
| 49 | + | id, err := strconv.ParseInt(string(item.Value), 10, 64) | |||
| 50 | + | if err != nil { | |||
| 51 | + | return domain.Release{}, err | |||
| 52 | + | } | |||
| 53 | + | item, ok = snap.Get(ctx, relKey(repo, id)) | |||
| 54 | + | if !ok { | |||
| 55 | + | return domain.Release{}, domain.ErrNotFound | |||
| 56 | + | } | |||
| 57 | + | return decodeRelease(item) | |||
| 58 | + | } | |||
| 40 | func encodeRelease(r domain.Release) []byte { | 59 | func encodeRelease(r domain.Release) []byte { | ||
| 41 | return mustMarshal(&storagepb.Release{ | 60 | return mustMarshal(&storagepb.Release{ | ||
| 42 | Id: r.ID, | 61 | Id: r.ID, | ||
| @@ -285,6 +304,13 @@ func (c *Releases) ApplyReleases(ctx context.Context, w ports.ReleaseWrite) erro | |||||
| 285 | b.RequireVersion(relUseKey(w.Repo), w.UsageVersion) | 304 | b.RequireVersion(relUseKey(w.Repo), w.UsageVersion) | ||
| 286 | } | 305 | } | ||
| 287 | b.Put(relUseKey(w.Repo), mustMarshal(&storagepb.ReleaseUsage{Used: w.Used})) | 306 | b.Put(relUseKey(w.Repo), mustMarshal(&storagepb.ReleaseUsage{Used: w.Used})) | ||
| 307 | + | if w.SetLatest { | |||
| 308 | + | if w.LatestID > 0 { | |||
| 309 | + | b.Put(relLatestKey(w.Repo), []byte(strconv.FormatInt(w.LatestID, 10))) | |||
| 310 | + | } else { | |||
| 311 | + | b.Delete(relLatestKey(w.Repo)) | |||
| 312 | + | } | |||
| 313 | + | } | |||
| 288 | snap := c.db.Snapshot(ctx) | 314 | snap := c.db.Snapshot(ctx) | ||
| 289 | for _, r := range w.DeleteReleases { | 315 | for _, r := range w.DeleteReleases { | ||
| 290 | if r.Repo != w.Repo || r.Version == 0 { | 316 | if r.Repo != w.Repo || r.Version == 0 { | ||
| @@ -388,7 +414,7 @@ func (c *Releases) ApplyReleases(ctx context.Context, w ports.ReleaseWrite) erro | |||||
| 388 | 414 | ||||
| 389 | // releaseKeys collects all repository-owned release keys, including global indexes. | 415 | // releaseKeys collects all repository-owned release keys, including global indexes. | ||
| 390 | func releaseKeys(ctx context.Context, snap *kv.Snapshot, repo domain.RepoName) [][]byte { | 416 | func releaseKeys(ctx context.Context, snap *kv.Snapshot, repo domain.RepoName) [][]byte { | ||
| 391 | - | keys := [][]byte{relUseKey(repo)} | 417 | + | keys := [][]byte{relUseKey(repo), relLatestKey(repo)} |
| 392 | for _, prefix := range []string{"rel/", "reltag/", "relassets/"} { | 418 | for _, prefix := range []string{"rel/", "reltag/", "relassets/"} { | ||
| 393 | for key, item := range snap.Prefix(ctx, []byte(prefix+repo.String()+"/")) { | 419 | for key, item := range snap.Prefix(ctx, []byte(prefix+repo.String()+"/")) { | ||
| 394 | keys = append(keys, slices.Clone(key)) | 420 | keys = append(keys, slices.Clone(key)) | ||
A internal/adapters/kvstore/releases_index.go +67 -0
| @@ -0,0 +1,67 @@ | |||
| 1 | + | // SPDX-License-Identifier: AGPL-3.0-or-later | |
| 2 | + | package kvstore | |
| 3 | + | ||
| 4 | + | import ( | |
| 5 | + | "context" | |
| 6 | + | "fmt" | |
| 7 | + | "strconv" | |
| 8 | + | ||
| 9 | + | kv "bnema.dev/ermite-kv" | |
| 10 | + | "bnema.dev/ermite/internal/domain" | |
| 11 | + | ) | |
| 12 | + | ||
| 13 | + | const releaseLatestIndexMarker = "meta/release-latest-index" | |
| 14 | + | ||
| 15 | + | // buildReleaseLatestIndex runs before the store is exposed to writers. A crash | |
| 16 | + | // before the marker is written safely repeats the pass on the next open. | |
| 17 | + | // Selection remains owned by domain.LatestRelease. | |
| 18 | + | func (s *Store) buildReleaseLatestIndex(ctx context.Context) error { | |
| 19 | + | if _, ok := s.db.Get(ctx, []byte(releaseLatestIndexMarker)); ok { | |
| 20 | + | return nil | |
| 21 | + | } | |
| 22 | + | var repo domain.RepoName | |
| 23 | + | var best domain.Release | |
| 24 | + | var eligible bool | |
| 25 | + | flush := func() error { | |
| 26 | + | var b kv.Batch | |
| 27 | + | if eligible { | |
| 28 | + | b.Put(relLatestKey(repo), []byte(strconv.FormatInt(best.ID, 10))) | |
| 29 | + | } else { | |
| 30 | + | b.Delete(relLatestKey(repo)) | |
| 31 | + | } | |
| 32 | + | if _, err := s.db.Apply(ctx, &b); err != nil { | |
| 33 | + | return fmt.Errorf("build latest release index: %w", err) | |
| 34 | + | } | |
| 35 | + | return nil | |
| 36 | + | } | |
| 37 | + | haveRepo := false | |
| 38 | + | for _, item := range s.db.Snapshot(ctx).Prefix(ctx, []byte("rel/")) { | |
| 39 | + | rel, err := decodeRelease(item) | |
| 40 | + | if err != nil { | |
| 41 | + | return fmt.Errorf("build latest release index: %w", err) | |
| 42 | + | } | |
| 43 | + | if haveRepo && rel.Repo != repo { | |
| 44 | + | if err := flush(); err != nil { | |
| 45 | + | return err | |
| 46 | + | } | |
| 47 | + | best, eligible = domain.Release{}, false | |
| 48 | + | } | |
| 49 | + | repo, haveRepo = rel.Repo, true | |
| 50 | + | if eligible { | |
| 51 | + | best, eligible = domain.LatestRelease([]domain.Release{best, rel}) | |
| 52 | + | } else { | |
| 53 | + | best, eligible = domain.LatestRelease([]domain.Release{rel}) | |
| 54 | + | } | |
| 55 | + | } | |
| 56 | + | if haveRepo { | |
| 57 | + | if err := flush(); err != nil { | |
| 58 | + | return err | |
| 59 | + | } | |
| 60 | + | } | |
| 61 | + | var b kv.Batch | |
| 62 | + | b.Put([]byte(releaseLatestIndexMarker), []byte{1}) | |
| 63 | + | if _, err := s.db.Apply(ctx, &b); err != nil { | |
| 64 | + | return fmt.Errorf("mark latest release index: %w", err) | |
| 65 | + | } | |
| 66 | + | return nil | |
| 67 | + | } | |
| @@ -0,0 +1,67 @@ | |||||
| 1 | + | // SPDX-License-Identifier: AGPL-3.0-or-later | |||
| 2 | + | package kvstore | |||
| 3 | + | ||||
| 4 | + | import ( | |||
| 5 | + | "context" | |||
| 6 | + | "fmt" | |||
| 7 | + | "strconv" | |||
| 8 | + | ||||
| 9 | + | kv "bnema.dev/ermite-kv" | |||
| 10 | + | "bnema.dev/ermite/internal/domain" | |||
| 11 | + | ) | |||
| 12 | + | ||||
| 13 | + | const releaseLatestIndexMarker = "meta/release-latest-index" | |||
| 14 | + | ||||
| 15 | + | // buildReleaseLatestIndex runs before the store is exposed to writers. A crash | |||
| 16 | + | // before the marker is written safely repeats the pass on the next open. | |||
| 17 | + | // Selection remains owned by domain.LatestRelease. | |||
| 18 | + | func (s *Store) buildReleaseLatestIndex(ctx context.Context) error { | |||
| 19 | + | if _, ok := s.db.Get(ctx, []byte(releaseLatestIndexMarker)); ok { | |||
| 20 | + | return nil | |||
| 21 | + | } | |||
| 22 | + | var repo domain.RepoName | |||
| 23 | + | var best domain.Release | |||
| 24 | + | var eligible bool | |||
| 25 | + | flush := func() error { | |||
| 26 | + | var b kv.Batch | |||
| 27 | + | if eligible { | |||
| 28 | + | b.Put(relLatestKey(repo), []byte(strconv.FormatInt(best.ID, 10))) | |||
| 29 | + | } else { | |||
| 30 | + | b.Delete(relLatestKey(repo)) | |||
| 31 | + | } | |||
| 32 | + | if _, err := s.db.Apply(ctx, &b); err != nil { | |||
| 33 | + | return fmt.Errorf("build latest release index: %w", err) | |||
| 34 | + | } | |||
| 35 | + | return nil | |||
| 36 | + | } | |||
| 37 | + | haveRepo := false | |||
| 38 | + | for _, item := range s.db.Snapshot(ctx).Prefix(ctx, []byte("rel/")) { | |||
| 39 | + | rel, err := decodeRelease(item) | |||
| 40 | + | if err != nil { | |||
| 41 | + | return fmt.Errorf("build latest release index: %w", err) | |||
| 42 | + | } | |||
| 43 | + | if haveRepo && rel.Repo != repo { | |||
| 44 | + | if err := flush(); err != nil { | |||
| 45 | + | return err | |||
| 46 | + | } | |||
| 47 | + | best, eligible = domain.Release{}, false | |||
| 48 | + | } | |||
| 49 | + | repo, haveRepo = rel.Repo, true | |||
| 50 | + | if eligible { | |||
| 51 | + | best, eligible = domain.LatestRelease([]domain.Release{best, rel}) | |||
| 52 | + | } else { | |||
| 53 | + | best, eligible = domain.LatestRelease([]domain.Release{rel}) | |||
| 54 | + | } | |||
| 55 | + | } | |||
| 56 | + | if haveRepo { | |||
| 57 | + | if err := flush(); err != nil { | |||
| 58 | + | return err | |||
| 59 | + | } | |||
| 60 | + | } | |||
| 61 | + | var b kv.Batch | |||
| 62 | + | b.Put([]byte(releaseLatestIndexMarker), []byte{1}) | |||
| 63 | + | if _, err := s.db.Apply(ctx, &b); err != nil { | |||
| 64 | + | return fmt.Errorf("mark latest release index: %w", err) | |||
| 65 | + | } | |||
| 66 | + | return nil | |||
| 67 | + | } | |||
A internal/adapters/kvstore/releases_index_test.go +97 -0
| @@ -0,0 +1,97 @@ | |||
| 1 | + | // SPDX-License-Identifier: AGPL-3.0-or-later | |
| 2 | + | package kvstore | |
| 3 | + | ||
| 4 | + | import ( | |
| 5 | + | "context" | |
| 6 | + | "testing" | |
| 7 | + | "time" | |
| 8 | + | ||
| 9 | + | kv "bnema.dev/ermite-kv" | |
| 10 | + | "bnema.dev/ermite/internal/domain" | |
| 11 | + | "bnema.dev/ermite/internal/ports" | |
| 12 | + | "github.com/stretchr/testify/require" | |
| 13 | + | ) | |
| 14 | + | ||
| 15 | + | func TestReleaseLatestIndexBackfill(t *testing.T) { | |
| 16 | + | ctx := t.Context() | |
| 17 | + | dir := t.TempDir() | |
| 18 | + | s, err := Open(ctx, dir) | |
| 19 | + | require.NoError(t, err) | |
| 20 | + | var repos []domain.RepoName | |
| 21 | + | for _, raw := range []string{"backfill", "empty", "newest"} { | |
| 22 | + | repo, err := domain.ParseRepoName(raw) | |
| 23 | + | require.NoError(t, err) | |
| 24 | + | repos = append(repos, repo) | |
| 25 | + | } | |
| 26 | + | for _, repo := range repos { | |
| 27 | + | require.NoError(t, s.Create(ctx, domain.Repo{Name: repo, Visibility: domain.VisibilityPublic})) | |
| 28 | + | } | |
| 29 | + | var b kv.Batch | |
| 30 | + | for i, repo := range repos { | |
| 31 | + | for j := 1; j <= 5; j++ { | |
| 32 | + | rel := domain.Release{ID: int64(i*10 + j), Repo: repo, Tag: string(rune('a' + j)), CreatedAt: time.Unix(int64(j), 0)} | |
| 33 | + | rel.Draft = j == 5 || i == 1 | |
| 34 | + | rel.Prerelease = j == 4 | |
| 35 | + | rel.MakeLatest = j == 1 && i == 0 | |
| 36 | + | b.Put(relKey(repo, rel.ID), encodeRelease(rel)) | |
| 37 | + | } | |
| 38 | + | // A stale key must also be removed for a repo with no eligible release. | |
| 39 | + | b.Put(relLatestKey(repo), []byte("999")) | |
| 40 | + | } | |
| 41 | + | b.Delete([]byte(releaseLatestIndexMarker)) | |
| 42 | + | _, err = s.db.Apply(ctx, &b) | |
| 43 | + | require.NoError(t, err) | |
| 44 | + | require.NoError(t, s.Close(context.Background())) | |
| 45 | + | s, err = Open(ctx, dir) | |
| 46 | + | require.NoError(t, err) | |
| 47 | + | defer func() { require.NoError(t, s.Close(context.Background())) }() | |
| 48 | + | for i, want := range []int64{1, 0, 23} { | |
| 49 | + | got, err := s.Releases().GetLatestRelease(ctx, repos[i]) | |
| 50 | + | if want == 0 { | |
| 51 | + | require.ErrorIs(t, err, domain.ErrNotFound) | |
| 52 | + | } else { | |
| 53 | + | require.NoError(t, err) | |
| 54 | + | require.Equal(t, want, got.ID) | |
| 55 | + | } | |
| 56 | + | } | |
| 57 | + | require.NoError(t, s.buildReleaseLatestIndex(ctx)) | |
| 58 | + | got, err := s.Releases().GetLatestRelease(ctx, repos[0]) | |
| 59 | + | require.NoError(t, err) | |
| 60 | + | require.EqualValues(t, 1, got.ID) | |
| 61 | + | require.NoError(t, s.Delete(ctx, repos[0])) | |
| 62 | + | _, err = s.Releases().GetLatestRelease(ctx, repos[0]) | |
| 63 | + | require.ErrorIs(t, err, domain.ErrNotFound) | |
| 64 | + | } | |
| 65 | + | ||
| 66 | + | func TestGetLatestReleaseAtomicUpdate(t *testing.T) { | |
| 67 | + | ctx := t.Context() | |
| 68 | + | s, err := Open(ctx, t.TempDir()) | |
| 69 | + | require.NoError(t, err) | |
| 70 | + | defer func() { require.NoError(t, s.Close(context.Background())) }() | |
| 71 | + | repo, err := domain.ParseRepoName("atomic") | |
| 72 | + | require.NoError(t, err) | |
| 73 | + | require.NoError(t, s.Create(ctx, domain.Repo{Name: repo, Visibility: domain.VisibilityPublic})) | |
| 74 | + | a := domain.Release{ID: 1, Repo: repo, Tag: "a"} | |
| 75 | + | b := domain.Release{ID: 2, Repo: repo, Tag: "b"} | |
| 76 | + | store := s.Releases() | |
| 77 | + | require.NoError(t, store.ApplyReleases(ctx, ports.ReleaseWrite{Repo: repo, PutReleases: []domain.Release{a, b}, SetLatest: true, LatestID: a.ID})) | |
| 78 | + | a, err = store.GetLatestRelease(ctx, repo) | |
| 79 | + | require.NoError(t, err) | |
| 80 | + | require.EqualValues(t, 1, a.ID) | |
| 81 | + | _, version, err := store.ReleaseUsage(ctx, repo) | |
| 82 | + | require.NoError(t, err) | |
| 83 | + | a.Prerelease = true | |
| 84 | + | require.NoError(t, store.ApplyReleases(ctx, ports.ReleaseWrite{Repo: repo, UsageVersion: version, PutReleases: []domain.Release{a}, SetLatest: true, LatestID: b.ID})) | |
| 85 | + | got, err := store.GetLatestRelease(ctx, repo) | |
| 86 | + | require.NoError(t, err) | |
| 87 | + | require.EqualValues(t, 2, got.ID) | |
| 88 | + | // An asset-only/usage write leaves the index untouched, including its version. | |
| 89 | + | before, ok := s.db.Get(ctx, relLatestKey(repo)) | |
| 90 | + | require.True(t, ok) | |
| 91 | + | _, version, err = store.ReleaseUsage(ctx, repo) | |
| 92 | + | require.NoError(t, err) | |
| 93 | + | require.NoError(t, store.ApplyReleases(ctx, ports.ReleaseWrite{Repo: repo, UsageVersion: version, Used: 10})) | |
| 94 | + | after, ok := s.db.Get(ctx, relLatestKey(repo)) | |
| 95 | + | require.True(t, ok) | |
| 96 | + | require.Equal(t, before, after) | |
| 97 | + | } | |
| @@ -0,0 +1,97 @@ | |||||
| 1 | + | // SPDX-License-Identifier: AGPL-3.0-or-later | |||
| 2 | + | package kvstore | |||
| 3 | + | ||||
| 4 | + | import ( | |||
| 5 | + | "context" | |||
| 6 | + | "testing" | |||
| 7 | + | "time" | |||
| 8 | + | ||||
| 9 | + | kv "bnema.dev/ermite-kv" | |||
| 10 | + | "bnema.dev/ermite/internal/domain" | |||
| 11 | + | "bnema.dev/ermite/internal/ports" | |||
| 12 | + | "github.com/stretchr/testify/require" | |||
| 13 | + | ) | |||
| 14 | + | ||||
| 15 | + | func TestReleaseLatestIndexBackfill(t *testing.T) { | |||
| 16 | + | ctx := t.Context() | |||
| 17 | + | dir := t.TempDir() | |||
| 18 | + | s, err := Open(ctx, dir) | |||
| 19 | + | require.NoError(t, err) | |||
| 20 | + | var repos []domain.RepoName | |||
| 21 | + | for _, raw := range []string{"backfill", "empty", "newest"} { | |||
| 22 | + | repo, err := domain.ParseRepoName(raw) | |||
| 23 | + | require.NoError(t, err) | |||
| 24 | + | repos = append(repos, repo) | |||
| 25 | + | } | |||
| 26 | + | for _, repo := range repos { | |||
| 27 | + | require.NoError(t, s.Create(ctx, domain.Repo{Name: repo, Visibility: domain.VisibilityPublic})) | |||
| 28 | + | } | |||
| 29 | + | var b kv.Batch | |||
| 30 | + | for i, repo := range repos { | |||
| 31 | + | for j := 1; j <= 5; j++ { | |||
| 32 | + | rel := domain.Release{ID: int64(i*10 + j), Repo: repo, Tag: string(rune('a' + j)), CreatedAt: time.Unix(int64(j), 0)} | |||
| 33 | + | rel.Draft = j == 5 || i == 1 | |||
| 34 | + | rel.Prerelease = j == 4 | |||
| 35 | + | rel.MakeLatest = j == 1 && i == 0 | |||
| 36 | + | b.Put(relKey(repo, rel.ID), encodeRelease(rel)) | |||
| 37 | + | } | |||
| 38 | + | // A stale key must also be removed for a repo with no eligible release. | |||
| 39 | + | b.Put(relLatestKey(repo), []byte("999")) | |||
| 40 | + | } | |||
| 41 | + | b.Delete([]byte(releaseLatestIndexMarker)) | |||
| 42 | + | _, err = s.db.Apply(ctx, &b) | |||
| 43 | + | require.NoError(t, err) | |||
| 44 | + | require.NoError(t, s.Close(context.Background())) | |||
| 45 | + | s, err = Open(ctx, dir) | |||
| 46 | + | require.NoError(t, err) | |||
| 47 | + | defer func() { require.NoError(t, s.Close(context.Background())) }() | |||
| 48 | + | for i, want := range []int64{1, 0, 23} { | |||
| 49 | + | got, err := s.Releases().GetLatestRelease(ctx, repos[i]) | |||
| 50 | + | if want == 0 { | |||
| 51 | + | require.ErrorIs(t, err, domain.ErrNotFound) | |||
| 52 | + | } else { | |||
| 53 | + | require.NoError(t, err) | |||
| 54 | + | require.Equal(t, want, got.ID) | |||
| 55 | + | } | |||
| 56 | + | } | |||
| 57 | + | require.NoError(t, s.buildReleaseLatestIndex(ctx)) | |||
| 58 | + | got, err := s.Releases().GetLatestRelease(ctx, repos[0]) | |||
| 59 | + | require.NoError(t, err) | |||
| 60 | + | require.EqualValues(t, 1, got.ID) | |||
| 61 | + | require.NoError(t, s.Delete(ctx, repos[0])) | |||
| 62 | + | _, err = s.Releases().GetLatestRelease(ctx, repos[0]) | |||
| 63 | + | require.ErrorIs(t, err, domain.ErrNotFound) | |||
| 64 | + | } | |||
| 65 | + | ||||
| 66 | + | func TestGetLatestReleaseAtomicUpdate(t *testing.T) { | |||
| 67 | + | ctx := t.Context() | |||
| 68 | + | s, err := Open(ctx, t.TempDir()) | |||
| 69 | + | require.NoError(t, err) | |||
| 70 | + | defer func() { require.NoError(t, s.Close(context.Background())) }() | |||
| 71 | + | repo, err := domain.ParseRepoName("atomic") | |||
| 72 | + | require.NoError(t, err) | |||
| 73 | + | require.NoError(t, s.Create(ctx, domain.Repo{Name: repo, Visibility: domain.VisibilityPublic})) | |||
| 74 | + | a := domain.Release{ID: 1, Repo: repo, Tag: "a"} | |||
| 75 | + | b := domain.Release{ID: 2, Repo: repo, Tag: "b"} | |||
| 76 | + | store := s.Releases() | |||
| 77 | + | require.NoError(t, store.ApplyReleases(ctx, ports.ReleaseWrite{Repo: repo, PutReleases: []domain.Release{a, b}, SetLatest: true, LatestID: a.ID})) | |||
| 78 | + | a, err = store.GetLatestRelease(ctx, repo) | |||
| 79 | + | require.NoError(t, err) | |||
| 80 | + | require.EqualValues(t, 1, a.ID) | |||
| 81 | + | _, version, err := store.ReleaseUsage(ctx, repo) | |||
| 82 | + | require.NoError(t, err) | |||
| 83 | + | a.Prerelease = true | |||
| 84 | + | require.NoError(t, store.ApplyReleases(ctx, ports.ReleaseWrite{Repo: repo, UsageVersion: version, PutReleases: []domain.Release{a}, SetLatest: true, LatestID: b.ID})) | |||
| 85 | + | got, err := store.GetLatestRelease(ctx, repo) | |||
| 86 | + | require.NoError(t, err) | |||
| 87 | + | require.EqualValues(t, 2, got.ID) | |||
| 88 | + | // An asset-only/usage write leaves the index untouched, including its version. | |||
| 89 | + | before, ok := s.db.Get(ctx, relLatestKey(repo)) | |||
| 90 | + | require.True(t, ok) | |||
| 91 | + | _, version, err = store.ReleaseUsage(ctx, repo) | |||
| 92 | + | require.NoError(t, err) | |||
| 93 | + | require.NoError(t, store.ApplyReleases(ctx, ports.ReleaseWrite{Repo: repo, UsageVersion: version, Used: 10})) | |||
| 94 | + | after, ok := s.db.Get(ctx, relLatestKey(repo)) | |||
| 95 | + | require.True(t, ok) | |||
| 96 | + | require.Equal(t, before, after) | |||
| 97 | + | } | |||
M internal/adapters/kvstore/store.go +6 -1
| @@ -43,7 +43,8 @@ import ( | |||
| 43 | 43 | // holding all eleven previous scopes, preserving their owner rights. Version 6 | |
| 44 | 44 | // adds releases and release:write; older builds cannot clean up their metadata | |
| 45 | 45 | // or preserve the owner rights of upgraded tokens (see upgradeReleaseTokens). | |
| 46 | - | const SchemaVersion = 6 | |
| 46 | + | // Version 7 adds the latest-release index; older writers would leave it stale. | |
| 47 | + | const SchemaVersion = 7 | |
| 47 | 48 | ||
| 48 | 49 | const schemaKey = "meta/schema" | |
| 49 | 50 | ||
| @@ -76,6 +77,10 @@ func Open(ctx context.Context, dir string) (*Store, error) { | |||
| 76 | 77 | _ = db.Close(context.WithoutCancel(ctx)) | |
| 77 | 78 | return nil, err | |
| 78 | 79 | } | |
| 80 | + | if err := s.buildReleaseLatestIndex(ctx); err != nil { | |
| 81 | + | _ = db.Close(context.WithoutCancel(ctx)) | |
| 82 | + | return nil, err | |
| 83 | + | } | |
| 79 | 84 | return s, nil | |
| 80 | 85 | } | |
| 81 | 86 | ||
| @@ -43,7 +43,8 @@ import ( | |||||
| 43 | // holding all eleven previous scopes, preserving their owner rights. Version 6 | 43 | // holding all eleven previous scopes, preserving their owner rights. Version 6 | ||
| 44 | // adds releases and release:write; older builds cannot clean up their metadata | 44 | // adds releases and release:write; older builds cannot clean up their metadata | ||
| 45 | // or preserve the owner rights of upgraded tokens (see upgradeReleaseTokens). | 45 | // or preserve the owner rights of upgraded tokens (see upgradeReleaseTokens). | ||
| 46 | - | const SchemaVersion = 6 | 46 | + | // Version 7 adds the latest-release index; older writers would leave it stale. |
| 47 | + | const SchemaVersion = 7 | |||
| 47 | 48 | ||||
| 48 | const schemaKey = "meta/schema" | 49 | const schemaKey = "meta/schema" | ||
| 49 | 50 | ||||
| @@ -76,6 +77,10 @@ func Open(ctx context.Context, dir string) (*Store, error) { | |||||
| 76 | _ = db.Close(context.WithoutCancel(ctx)) | 77 | _ = db.Close(context.WithoutCancel(ctx)) | ||
| 77 | return nil, err | 78 | return nil, err | ||
| 78 | } | 79 | } | ||
| 80 | + | if err := s.buildReleaseLatestIndex(ctx); err != nil { | |||
| 81 | + | _ = db.Close(context.WithoutCancel(ctx)) | |||
| 82 | + | return nil, err | |||
| 83 | + | } | |||
| 79 | return s, nil | 84 | return s, nil | ||
| 80 | } | 85 | } | ||
| 81 | 86 | ||||
M internal/adapters/web/fragments.go +1 -1
| @@ -167,7 +167,7 @@ func (l *liveStream) gone(ctx context.Context, name string) ([]fragment, error) | |||
| 167 | 167 | func (l *liveStream) repoPage(ctx context.Context, we ports.WatchEvent) ([]fragment, error) { | |
| 168 | 168 | switch ev := we.Event.(type) { | |
| 169 | 169 | case domain.ReleasePublished, domain.ReleaseUpdated, domain.ReleaseDeleted, domain.ReleaseUnpublished: | |
| 170 | - | if l.view == "releases" || l.view == "release" { | |
| 170 | + | if l.view == "releases" || l.view == "release" || l.view == "summary" { | |
| 171 | 171 | return gap, nil // notes, assets, latest or visibility changed: reload | |
| 172 | 172 | } | |
| 173 | 173 | return nil, nil | |
| @@ -167,7 +167,7 @@ func (l *liveStream) gone(ctx context.Context, name string) ([]fragment, error) | |||||
| 167 | func (l *liveStream) repoPage(ctx context.Context, we ports.WatchEvent) ([]fragment, error) { | 167 | func (l *liveStream) repoPage(ctx context.Context, we ports.WatchEvent) ([]fragment, error) { | ||
| 168 | switch ev := we.Event.(type) { | 168 | switch ev := we.Event.(type) { | ||
| 169 | case domain.ReleasePublished, domain.ReleaseUpdated, domain.ReleaseDeleted, domain.ReleaseUnpublished: | 169 | case domain.ReleasePublished, domain.ReleaseUpdated, domain.ReleaseDeleted, domain.ReleaseUnpublished: | ||
| 170 | - | if l.view == "releases" || l.view == "release" { | 170 | + | if l.view == "releases" || l.view == "release" || l.view == "summary" { |
| 171 | return gap, nil // notes, assets, latest or visibility changed: reload | 171 | return gap, nil // notes, assets, latest or visibility changed: reload | ||
| 172 | } | 172 | } | ||
| 173 | return nil, nil | 173 | return nil, nil | ||
M internal/adapters/web/fragments_test.go +3 -3
| @@ -101,8 +101,8 @@ func TestMRPushedHeadSignal(t *testing.T) { | |||
| 101 | 101 | } | |
| 102 | 102 | } | |
| 103 | 103 | ||
| 104 | - | // Release lifecycle events invalidate the release pages without putting notes | |
| 105 | - | // or asset metadata in SSE payloads. Other views need no release fragments. | |
| 104 | + | // Release lifecycle events invalidate release pages and the summary's release | |
| 105 | + | // fact without putting notes or asset metadata in SSE payloads. | |
| 106 | 106 | func TestReleaseLiveUpdates(t *testing.T) { | |
| 107 | 107 | for _, ev := range []domain.Event{domain.ReleasePublished{}, domain.ReleaseUpdated{}, domain.ReleaseDeleted{}, domain.ReleaseUnpublished{}} { | |
| 108 | 108 | we := ports.WatchEvent{Event: ev} | |
| @@ -111,7 +111,7 @@ func TestReleaseLiveUpdates(t *testing.T) { | |||
| 111 | 111 | st := &liveStream{repo: "proj", view: view} | |
| 112 | 112 | got, err := st.render(t.Context(), we) | |
| 113 | 113 | require.NoError(t, err) | |
| 114 | - | if view == "release" || view == "releases" { | |
| 114 | + | if view == "release" || view == "releases" || view == "summary" { | |
| 115 | 115 | assert.Equal(t, gap, got) | |
| 116 | 116 | } else { | |
| 117 | 117 | assert.Empty(t, got) | |
| @@ -101,8 +101,8 @@ func TestMRPushedHeadSignal(t *testing.T) { | |||||
| 101 | } | 101 | } | ||
| 102 | } | 102 | } | ||
| 103 | 103 | ||||
| 104 | - | // Release lifecycle events invalidate the release pages without putting notes | 104 | + | // Release lifecycle events invalidate release pages and the summary's release |
| 105 | - | // or asset metadata in SSE payloads. Other views need no release fragments. | 105 | + | // fact without putting notes or asset metadata in SSE payloads. |
| 106 | func TestReleaseLiveUpdates(t *testing.T) { | 106 | func TestReleaseLiveUpdates(t *testing.T) { | ||
| 107 | for _, ev := range []domain.Event{domain.ReleasePublished{}, domain.ReleaseUpdated{}, domain.ReleaseDeleted{}, domain.ReleaseUnpublished{}} { | 107 | for _, ev := range []domain.Event{domain.ReleasePublished{}, domain.ReleaseUpdated{}, domain.ReleaseDeleted{}, domain.ReleaseUnpublished{}} { | ||
| 108 | we := ports.WatchEvent{Event: ev} | 108 | we := ports.WatchEvent{Event: ev} | ||
| @@ -111,7 +111,7 @@ func TestReleaseLiveUpdates(t *testing.T) { | |||||
| 111 | st := &liveStream{repo: "proj", view: view} | 111 | st := &liveStream{repo: "proj", view: view} | ||
| 112 | got, err := st.render(t.Context(), we) | 112 | got, err := st.render(t.Context(), we) | ||
| 113 | require.NoError(t, err) | 113 | require.NoError(t, err) | ||
| 114 | - | if view == "release" || view == "releases" { | 114 | + | if view == "release" || view == "releases" || view == "summary" { |
| 115 | assert.Equal(t, gap, got) | 115 | assert.Equal(t, gap, got) | ||
| 116 | } else { | 116 | } else { | ||
| 117 | assert.Empty(t, got) | 117 | assert.Empty(t, got) | ||
M internal/adapters/web/issues_test.go +3 -3
| @@ -100,7 +100,7 @@ func TestIssueList(t *testing.T) { | |||
| 100 | 100 | assert.Contains(t, body, "crash <b>on</b> start") | |
| 101 | 101 | assert.Contains(t, body, `href="/proj/issues?page=tok2"`, "older page") | |
| 102 | 102 | assert.Contains(t, body, `href="/proj/issues?state=closed"`, "closed tab") | |
| 103 | - | assert.Contains(t, body, `href="/proj/issues" data-key="i"`, "the Issues tab") | |
| 103 | + | assert.Contains(t, body, `href="/proj/issues" data-key="g i"`, "the Issues tab") | |
| 104 | 104 | assert.NotContains(t, body, "New issue", "no form for an anonymous visitor") | |
| 105 | 105 | assert.Equal(t, "no-cache", rec.Header().Get("Cache-Control")) | |
| 106 | 106 | ||
| @@ -169,7 +169,7 @@ func TestIssueNotFound(t *testing.T) { | |||
| 169 | 169 | } | |
| 170 | 170 | summary := off.do("GET", "/proj", false, nil) | |
| 171 | 171 | require.Equal(t, 200, summary.Code) | |
| 172 | - | assert.NotContains(t, summary.Body.String(), `data-key="i"`) | |
| 172 | + | assert.NotContains(t, summary.Body.String(), `data-key="g i"`) | |
| 173 | 173 | ||
| 174 | 174 | // The mode is unset in the settings: off as well. | |
| 175 | 175 | unset := newIssueRig(t, "", false) | |
| @@ -257,7 +257,7 @@ func TestIssueRoutesAbsentWithoutService(t *testing.T) { | |||
| 257 | 257 | } | |
| 258 | 258 | rec := httptest.NewRecorder() | |
| 259 | 259 | srv.ServeHTTP(rec, httptest.NewRequest("GET", "/proj", nil)) | |
| 260 | - | assert.NotContains(t, rec.Body.String(), `data-key="i"`) | |
| 260 | + | assert.NotContains(t, rec.Body.String(), `data-key="g i"`) | |
| 261 | 261 | } | |
| 262 | 262 | ||
| 263 | 263 | func TestIssueNumberRedirects(t *testing.T) { | |
| @@ -100,7 +100,7 @@ func TestIssueList(t *testing.T) { | |||||
| 100 | assert.Contains(t, body, "crash <b>on</b> start") | 100 | assert.Contains(t, body, "crash <b>on</b> start") | ||
| 101 | assert.Contains(t, body, `href="/proj/issues?page=tok2"`, "older page") | 101 | assert.Contains(t, body, `href="/proj/issues?page=tok2"`, "older page") | ||
| 102 | assert.Contains(t, body, `href="/proj/issues?state=closed"`, "closed tab") | 102 | assert.Contains(t, body, `href="/proj/issues?state=closed"`, "closed tab") | ||
| 103 | - | assert.Contains(t, body, `href="/proj/issues" data-key="i"`, "the Issues tab") | 103 | + | assert.Contains(t, body, `href="/proj/issues" data-key="g i"`, "the Issues tab") |
| 104 | assert.NotContains(t, body, "New issue", "no form for an anonymous visitor") | 104 | assert.NotContains(t, body, "New issue", "no form for an anonymous visitor") | ||
| 105 | assert.Equal(t, "no-cache", rec.Header().Get("Cache-Control")) | 105 | assert.Equal(t, "no-cache", rec.Header().Get("Cache-Control")) | ||
| 106 | 106 | ||||
| @@ -169,7 +169,7 @@ func TestIssueNotFound(t *testing.T) { | |||||
| 169 | } | 169 | } | ||
| 170 | summary := off.do("GET", "/proj", false, nil) | 170 | summary := off.do("GET", "/proj", false, nil) | ||
| 171 | require.Equal(t, 200, summary.Code) | 171 | require.Equal(t, 200, summary.Code) | ||
| 172 | - | assert.NotContains(t, summary.Body.String(), `data-key="i"`) | 172 | + | assert.NotContains(t, summary.Body.String(), `data-key="g i"`) |
| 173 | 173 | ||||
| 174 | // The mode is unset in the settings: off as well. | 174 | // The mode is unset in the settings: off as well. | ||
| 175 | unset := newIssueRig(t, "", false) | 175 | unset := newIssueRig(t, "", false) | ||
| @@ -257,7 +257,7 @@ func TestIssueRoutesAbsentWithoutService(t *testing.T) { | |||||
| 257 | } | 257 | } | ||
| 258 | rec := httptest.NewRecorder() | 258 | rec := httptest.NewRecorder() | ||
| 259 | srv.ServeHTTP(rec, httptest.NewRequest("GET", "/proj", nil)) | 259 | srv.ServeHTTP(rec, httptest.NewRequest("GET", "/proj", nil)) | ||
| 260 | - | assert.NotContains(t, rec.Body.String(), `data-key="i"`) | 260 | + | assert.NotContains(t, rec.Body.String(), `data-key="g i"`) |
| 261 | } | 261 | } | ||
| 262 | 262 | ||||
| 263 | func TestIssueNumberRedirects(t *testing.T) { | 263 | func TestIssueNumberRedirects(t *testing.T) { | ||
A internal/adapters/web/jstest/keyboard.test.mjs +76 -0
| @@ -0,0 +1,76 @@ | |||
| 1 | + | // Exercise the production key handler without a browser or dependencies. | |
| 2 | + | import assert from 'node:assert/strict'; | |
| 3 | + | import { readFileSync } from 'node:fs'; | |
| 4 | + | import { test } from 'node:test'; | |
| 5 | + | import { runInNewContext } from 'node:vm'; | |
| 6 | + | const source = readFileSync(new URL('../static/js/ermite.js', import.meta.url), 'utf8'); | |
| 7 | + | function keyboard({ owner = true, off = false, typing = false, dialog = false } = {}) { | |
| 8 | + | let handler; | |
| 9 | + | const fired = []; | |
| 10 | + | const timers = new Map(); | |
| 11 | + | let timerID = 0; | |
| 12 | + | runInNewContext(source.slice(source.indexOf(' const single ='), source.indexOf(' // 2. A [data-fire]')), { | |
| 13 | + | addEventListener: (_, fn) => { handler = fn; }, | |
| 14 | + | window: { ermiteKeys: { blocks: () => off } }, | |
| 15 | + | ermite: { fire: name => fired.push(name) }, | |
| 16 | + | $: selector => (owner && selector === '[data-inbox]') || (dialog && selector === 'dialog[open]'), | |
| 17 | + | closeMenus: () => false, | |
| 18 | + | clearTimeout: id => timers.delete(id), | |
| 19 | + | setTimeout: fn => { timers.set(++timerID, fn); return timerID; }, | |
| 20 | + | }); | |
| 21 | + | return { fired, expireTimers() { | |
| 22 | + | const callbacks = [...timers.values()]; | |
| 23 | + | timers.clear(); | |
| 24 | + | for (const callback of callbacks) callback(); | |
| 25 | + | }, press(key, shiftKey = false) { | |
| 26 | + | handler({ key, shiftKey, target: { closest: selector => typing && selector.startsWith('input'), blur() {} }, preventDefault() {} }); | |
| 27 | + | } }; | |
| 28 | + | } | |
| 29 | + | test('sections require g and have no old t alias', () => { | |
| 30 | + | const k = keyboard(); | |
| 31 | + | for (const key of ['s', 't', 'c', 'r', 'm', 'i']) k.press(key); | |
| 32 | + | assert.deepEqual(k.fired, []); | |
| 33 | + | for (const key of ['s', 'f', 'c', 'b', 'm', 'i', 'r', 'a', 'h', 'g', 't']) { k.press('g'); k.press(key); } | |
| 34 | + | assert.deepEqual(k.fired, ['s', 'f', 'c', 'b', 'm', 'i', 'r', 'a', 'gh', 'top']); | |
| 35 | + | }); | |
| 36 | + | test('uppercase actions work with either reported casing and interrupt prefixes', () => { | |
| 37 | + | for (const [key, action] of Object.entries({ G: 'bottom', M: 'merge', R: 'read', E: 'expandAll', I: 'inbox' })) { | |
| 38 | + | for (const reported of [key, key.toLowerCase()]) { | |
| 39 | + | const k = keyboard(); | |
| 40 | + | k.press('g'); k.press(reported, true); k.press(reported, true); | |
| 41 | + | assert.deepEqual(k.fired, [action, action]); | |
| 42 | + | } | |
| 43 | + | } | |
| 44 | + | }); | |
| 45 | + | test('uppercase actions respect preference, fields and dialogs', () => { | |
| 46 | + | for (const options of [{ off: true }, { typing: true }, { dialog: true }]) { | |
| 47 | + | const k = keyboard(options); k.press('g', true); | |
| 48 | + | assert.deepEqual(k.fired, []); | |
| 49 | + | } | |
| 50 | + | }); | |
| 51 | + | ||
| 52 | + | test('Shift+I opens inbox while issues need the g i sequence', () => { | |
| 53 | + | const k = keyboard(); | |
| 54 | + | k.press('I', true); k.press('i'); | |
| 55 | + | assert.deepEqual(k.fired, ['inbox']); | |
| 56 | + | k.press('g'); k.press('i'); | |
| 57 | + | assert.deepEqual(k.fired, ['inbox', 'i']); | |
| 58 | + | }); | |
| 59 | + | test('inbox shortcut respects preference, fields, dialogs, and owner target', () => { | |
| 60 | + | for (const options of [{ off: true }, { typing: true }, { dialog: true }, { owner: false }]) { | |
| 61 | + | const k = keyboard(options); k.press('I', true); | |
| 62 | + | assert.deepEqual(k.fired, [], JSON.stringify(options)); | |
| 63 | + | } | |
| 64 | + | }); | |
| 65 | + | test('shifted punctuation still opens help and the command palette', () => { | |
| 66 | + | const k = keyboard(); | |
| 67 | + | k.press('?', true); k.press(':', true); | |
| 68 | + | assert.deepEqual(k.fired, ['help', 'cmd']); | |
| 69 | + | }); | |
| 70 | + | test('g prefix expires without scheduling real timers', () => { | |
| 71 | + | const k = keyboard(); | |
| 72 | + | k.press('g'); k.expireTimers(); k.press('s'); | |
| 73 | + | assert.deepEqual(k.fired, []); | |
| 74 | + | k.press('g'); k.press('s'); | |
| 75 | + | assert.deepEqual(k.fired, ['s']); | |
| 76 | + | }); | |
| @@ -0,0 +1,76 @@ | |||||
| 1 | + | // Exercise the production key handler without a browser or dependencies. | |||
| 2 | + | import assert from 'node:assert/strict'; | |||
| 3 | + | import { readFileSync } from 'node:fs'; | |||
| 4 | + | import { test } from 'node:test'; | |||
| 5 | + | import { runInNewContext } from 'node:vm'; | |||
| 6 | + | const source = readFileSync(new URL('../static/js/ermite.js', import.meta.url), 'utf8'); | |||
| 7 | + | function keyboard({ owner = true, off = false, typing = false, dialog = false } = {}) { | |||
| 8 | + | let handler; | |||
| 9 | + | const fired = []; | |||
| 10 | + | const timers = new Map(); | |||
| 11 | + | let timerID = 0; | |||
| 12 | + | runInNewContext(source.slice(source.indexOf(' const single ='), source.indexOf(' // 2. A [data-fire]')), { | |||
| 13 | + | addEventListener: (_, fn) => { handler = fn; }, | |||
| 14 | + | window: { ermiteKeys: { blocks: () => off } }, | |||
| 15 | + | ermite: { fire: name => fired.push(name) }, | |||
| 16 | + | $: selector => (owner && selector === '[data-inbox]') || (dialog && selector === 'dialog[open]'), | |||
| 17 | + | closeMenus: () => false, | |||
| 18 | + | clearTimeout: id => timers.delete(id), | |||
| 19 | + | setTimeout: fn => { timers.set(++timerID, fn); return timerID; }, | |||
| 20 | + | }); | |||
| 21 | + | return { fired, expireTimers() { | |||
| 22 | + | const callbacks = [...timers.values()]; | |||
| 23 | + | timers.clear(); | |||
| 24 | + | for (const callback of callbacks) callback(); | |||
| 25 | + | }, press(key, shiftKey = false) { | |||
| 26 | + | handler({ key, shiftKey, target: { closest: selector => typing && selector.startsWith('input'), blur() {} }, preventDefault() {} }); | |||
| 27 | + | } }; | |||
| 28 | + | } | |||
| 29 | + | test('sections require g and have no old t alias', () => { | |||
| 30 | + | const k = keyboard(); | |||
| 31 | + | for (const key of ['s', 't', 'c', 'r', 'm', 'i']) k.press(key); | |||
| 32 | + | assert.deepEqual(k.fired, []); | |||
| 33 | + | for (const key of ['s', 'f', 'c', 'b', 'm', 'i', 'r', 'a', 'h', 'g', 't']) { k.press('g'); k.press(key); } | |||
| 34 | + | assert.deepEqual(k.fired, ['s', 'f', 'c', 'b', 'm', 'i', 'r', 'a', 'gh', 'top']); | |||
| 35 | + | }); | |||
| 36 | + | test('uppercase actions work with either reported casing and interrupt prefixes', () => { | |||
| 37 | + | for (const [key, action] of Object.entries({ G: 'bottom', M: 'merge', R: 'read', E: 'expandAll', I: 'inbox' })) { | |||
| 38 | + | for (const reported of [key, key.toLowerCase()]) { | |||
| 39 | + | const k = keyboard(); | |||
| 40 | + | k.press('g'); k.press(reported, true); k.press(reported, true); | |||
| 41 | + | assert.deepEqual(k.fired, [action, action]); | |||
| 42 | + | } | |||
| 43 | + | } | |||
| 44 | + | }); | |||
| 45 | + | test('uppercase actions respect preference, fields and dialogs', () => { | |||
| 46 | + | for (const options of [{ off: true }, { typing: true }, { dialog: true }]) { | |||
| 47 | + | const k = keyboard(options); k.press('g', true); | |||
| 48 | + | assert.deepEqual(k.fired, []); | |||
| 49 | + | } | |||
| 50 | + | }); | |||
| 51 | + | ||||
| 52 | + | test('Shift+I opens inbox while issues need the g i sequence', () => { | |||
| 53 | + | const k = keyboard(); | |||
| 54 | + | k.press('I', true); k.press('i'); | |||
| 55 | + | assert.deepEqual(k.fired, ['inbox']); | |||
| 56 | + | k.press('g'); k.press('i'); | |||
| 57 | + | assert.deepEqual(k.fired, ['inbox', 'i']); | |||
| 58 | + | }); | |||
| 59 | + | test('inbox shortcut respects preference, fields, dialogs, and owner target', () => { | |||
| 60 | + | for (const options of [{ off: true }, { typing: true }, { dialog: true }, { owner: false }]) { | |||
| 61 | + | const k = keyboard(options); k.press('I', true); | |||
| 62 | + | assert.deepEqual(k.fired, [], JSON.stringify(options)); | |||
| 63 | + | } | |||
| 64 | + | }); | |||
| 65 | + | test('shifted punctuation still opens help and the command palette', () => { | |||
| 66 | + | const k = keyboard(); | |||
| 67 | + | k.press('?', true); k.press(':', true); | |||
| 68 | + | assert.deepEqual(k.fired, ['help', 'cmd']); | |||
| 69 | + | }); | |||
| 70 | + | test('g prefix expires without scheduling real timers', () => { | |||
| 71 | + | const k = keyboard(); | |||
| 72 | + | k.press('g'); k.expireTimers(); k.press('s'); | |||
| 73 | + | assert.deepEqual(k.fired, []); | |||
| 74 | + | k.press('g'); k.press('s'); | |||
| 75 | + | assert.deepEqual(k.fired, ['s']); | |||
| 76 | + | }); | |||
D internal/adapters/web/jstest/keys.test.mjs +0 -29
| @@ -1,29 +0,0 @@ | |||
| 1 | - | // Exercise the production keydown handler without loading the rest of the page. | |
| 2 | - | import assert from 'node:assert/strict'; | |
| 3 | - | import { readFileSync } from 'node:fs'; | |
| 4 | - | import { test } from 'node:test'; | |
| 5 | - | const src = readFileSync(new URL('../static/js/ermite.js', import.meta.url), 'utf8'); | |
| 6 | - | const block = src.slice(src.indexOf(' // 1. Keys.'), src.indexOf(' // 2. A [data-fire]')); | |
| 7 | - | ||
| 8 | - | function page({ owner = true, off = false, typing = false, dialog = false } = {}) { | |
| 9 | - | let handler; | |
| 10 | - | const fired = []; | |
| 11 | - | const window = { ermiteKeys: { blocks: () => off } }; | |
| 12 | - | const $ = (s) => s === 'dialog[open]' ? dialog : s === '[data-inbox]' ? owner : null; | |
| 13 | - | new Function('window', '$', 'ermite', 'addEventListener', block)(window, $, { fire: (n) => fired.push(n) }, (_, f) => { handler = f; }); | |
| 14 | - | return (key) => { | |
| 15 | - | const e = { key, shiftKey: key === 'I', preventDefault() {}, target: { closest: (s) => s.startsWith('input') && typing } }; | |
| 16 | - | handler(e); | |
| 17 | - | return fired; | |
| 18 | - | }; | |
| 19 | - | } | |
| 20 | - | test('Shift+I opens inbox while lowercase i retains the issues tab', () => { | |
| 21 | - | const press = page(); | |
| 22 | - | assert.deepEqual(press('I'), ['inbox']); | |
| 23 | - | assert.deepEqual(press('i'), ['inbox', 'i']); | |
| 24 | - | }); | |
| 25 | - | test('inbox shortcut respects preference, fields, dialogs, and owner target', () => { | |
| 26 | - | for (const options of [{ off: true }, { typing: true }, { dialog: true }, { owner: false }]) { | |
| 27 | - | assert.deepEqual(page(options)('I'), [], JSON.stringify(options)); | |
| 28 | - | } | |
| 29 | - | }); | |
| @@ -1,29 +0,0 @@ | |||||
| 1 | - | // Exercise the production keydown handler without loading the rest of the page. | |||
| 2 | - | import assert from 'node:assert/strict'; | |||
| 3 | - | import { readFileSync } from 'node:fs'; | |||
| 4 | - | import { test } from 'node:test'; | |||
| 5 | - | const src = readFileSync(new URL('../static/js/ermite.js', import.meta.url), 'utf8'); | |||
| 6 | - | const block = src.slice(src.indexOf(' // 1. Keys.'), src.indexOf(' // 2. A [data-fire]')); | |||
| 7 | - | ||||
| 8 | - | function page({ owner = true, off = false, typing = false, dialog = false } = {}) { | |||
| 9 | - | let handler; | |||
| 10 | - | const fired = []; | |||
| 11 | - | const window = { ermiteKeys: { blocks: () => off } }; | |||
| 12 | - | const $ = (s) => s === 'dialog[open]' ? dialog : s === '[data-inbox]' ? owner : null; | |||
| 13 | - | new Function('window', '$', 'ermite', 'addEventListener', block)(window, $, { fire: (n) => fired.push(n) }, (_, f) => { handler = f; }); | |||
| 14 | - | return (key) => { | |||
| 15 | - | const e = { key, shiftKey: key === 'I', preventDefault() {}, target: { closest: (s) => s.startsWith('input') && typing } }; | |||
| 16 | - | handler(e); | |||
| 17 | - | return fired; | |||
| 18 | - | }; | |||
| 19 | - | } | |||
| 20 | - | test('Shift+I opens inbox while lowercase i retains the issues tab', () => { | |||
| 21 | - | const press = page(); | |||
| 22 | - | assert.deepEqual(press('I'), ['inbox']); | |||
| 23 | - | assert.deepEqual(press('i'), ['inbox', 'i']); | |||
| 24 | - | }); | |||
| 25 | - | test('inbox shortcut respects preference, fields, dialogs, and owner target', () => { | |||
| 26 | - | for (const options of [{ off: true }, { typing: true }, { dialog: true }, { owner: false }]) { | |||
| 27 | - | assert.deepEqual(page(options)('I'), [], JSON.stringify(options)); | |||
| 28 | - | } | |||
| 29 | - | }); | |||
M internal/adapters/web/keys.templ +3 -2
| @@ -23,7 +23,9 @@ templ Keys() { | |||
| 23 | 23 | k-filter from:body -> ermite.focusFilter(); | |
| 24 | 24 | k-gh from:body -> ermite.go('.brand'); | |
| 25 | 25 | k-s from:body -> ermite.tab('s'); | |
| 26 | - | k-t from:body -> ermite.tab('t'); | |
| 26 | + | k-f from:body -> ermite.tab('f'); | |
| 27 | + | k-b from:body -> ermite.tab('b'); | |
| 28 | + | k-a from:body -> ermite.tab('a'); | |
| 27 | 29 | k-c from:body -> ermite.tab('c'); | |
| 28 | 30 | k-r from:body -> ermite.tab('r'); | |
| 29 | 31 | k-m from:body -> ermite.tab('m'); | |
| @@ -39,7 +41,6 @@ templ Keys() { | |||
| 39 | 41 | k-permalink from:body -> ermite.permalink(); | |
| 40 | 42 | k-merge from:body -> window.ermiteMR?.openMerge(); | |
| 41 | 43 | k-read from:body -> window.ermiteMR?.markRead(); | |
| 42 | - | k-gf from:body -> window.ermiteMR?.focusFiles(); | |
| 43 | 44 | k-keys from:body -> ermite.toggleKeys()" | |
| 44 | 45 | ></div> | |
| 45 | 46 | } | |
| @@ -23,7 +23,9 @@ templ Keys() { | |||||
| 23 | k-filter from:body -> ermite.focusFilter(); | 23 | k-filter from:body -> ermite.focusFilter(); | ||
| 24 | k-gh from:body -> ermite.go('.brand'); | 24 | k-gh from:body -> ermite.go('.brand'); | ||
| 25 | k-s from:body -> ermite.tab('s'); | 25 | k-s from:body -> ermite.tab('s'); | ||
| 26 | - | k-t from:body -> ermite.tab('t'); | 26 | + | k-f from:body -> ermite.tab('f'); |
| 27 | + | k-b from:body -> ermite.tab('b'); | |||
| 28 | + | k-a from:body -> ermite.tab('a'); | |||
| 27 | k-c from:body -> ermite.tab('c'); | 29 | k-c from:body -> ermite.tab('c'); | ||
| 28 | k-r from:body -> ermite.tab('r'); | 30 | k-r from:body -> ermite.tab('r'); | ||
| 29 | k-m from:body -> ermite.tab('m'); | 31 | k-m from:body -> ermite.tab('m'); | ||
| @@ -39,7 +41,6 @@ templ Keys() { | |||||
| 39 | k-permalink from:body -> ermite.permalink(); | 41 | k-permalink from:body -> ermite.permalink(); | ||
| 40 | k-merge from:body -> window.ermiteMR?.openMerge(); | 42 | k-merge from:body -> window.ermiteMR?.openMerge(); | ||
| 41 | k-read from:body -> window.ermiteMR?.markRead(); | 43 | k-read from:body -> window.ermiteMR?.markRead(); | ||
| 42 | - | k-gf from:body -> window.ermiteMR?.focusFiles(); | |||
| 43 | k-keys from:body -> ermite.toggleKeys()" | 44 | k-keys from:body -> ermite.toggleKeys()" | ||
| 44 | ></div> | 45 | ></div> | ||
| 45 | } | 46 | } | ||
M internal/adapters/web/keys_templ.go +1 -1 generated file: collapsed
A internal/adapters/web/keys_test.go +26 -0
| @@ -0,0 +1,26 @@ | |||
| 1 | + | // SPDX-License-Identifier: AGPL-3.0-or-later | |
| 2 | + | ||
| 3 | + | package web | |
| 4 | + | ||
| 5 | + | import ( | |
| 6 | + | "testing" | |
| 7 | + | ||
| 8 | + | "github.com/stretchr/testify/assert" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | func TestSectionShortcutSequences(t *testing.T) { | |
| 12 | + | sections := []Section{} | |
| 13 | + | for _, key := range []string{"s", "f", "c", "b", "m", "i", "r", "a"} { | |
| 14 | + | sections = append(sections, Section{Key: key, Label: key, Href: "/" + key}) | |
| 15 | + | } | |
| 16 | + | header := renderToString(t, Header(Layout{Sections: sections})) | |
| 17 | + | bindings := renderToString(t, Keys()) | |
| 18 | + | for _, section := range sections { | |
| 19 | + | assert.Contains(t, header, `data-key="g `+section.Key+`"`) | |
| 20 | + | assert.NotContains(t, header, `aria-keyshortcuts="g `+section.Key+`"`) | |
| 21 | + | assert.Contains(t, header, `<kbd aria-hidden="true">g `+section.Key+`</kbd>`) | |
| 22 | + | assert.Contains(t, bindings, "ermite.tab('"+section.Key+"')") | |
| 23 | + | } | |
| 24 | + | assert.NotContains(t, bindings, "k-gf") | |
| 25 | + | assert.NotContains(t, bindings, "k-t from:body") | |
| 26 | + | } | |
| @@ -0,0 +1,26 @@ | |||||
| 1 | + | // SPDX-License-Identifier: AGPL-3.0-or-later | |||
| 2 | + | ||||
| 3 | + | package web | |||
| 4 | + | ||||
| 5 | + | import ( | |||
| 6 | + | "testing" | |||
| 7 | + | ||||
| 8 | + | "github.com/stretchr/testify/assert" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | func TestSectionShortcutSequences(t *testing.T) { | |||
| 12 | + | sections := []Section{} | |||
| 13 | + | for _, key := range []string{"s", "f", "c", "b", "m", "i", "r", "a"} { | |||
| 14 | + | sections = append(sections, Section{Key: key, Label: key, Href: "/" + key}) | |||
| 15 | + | } | |||
| 16 | + | header := renderToString(t, Header(Layout{Sections: sections})) | |||
| 17 | + | bindings := renderToString(t, Keys()) | |||
| 18 | + | for _, section := range sections { | |||
| 19 | + | assert.Contains(t, header, `data-key="g `+section.Key+`"`) | |||
| 20 | + | assert.NotContains(t, header, `aria-keyshortcuts="g `+section.Key+`"`) | |||
| 21 | + | assert.Contains(t, header, `<kbd aria-hidden="true">g `+section.Key+`</kbd>`) | |||
| 22 | + | assert.Contains(t, bindings, "ermite.tab('"+section.Key+"')") | |||
| 23 | + | } | |||
| 24 | + | assert.NotContains(t, bindings, "k-gf") | |||
| 25 | + | assert.NotContains(t, bindings, "k-t from:body") | |||
| 26 | + | } | |||
M internal/adapters/web/mr.templ +1 -1
| @@ -430,7 +430,7 @@ templ mrFooter(p MRPage) { | |||
| 430 | 430 | templ mrRail(p MRPage) { | |
| 431 | 431 | <section aria-labelledby="r-files" class="r-files"> | |
| 432 | 432 | <h2 id="r-files"> | |
| 433 | - | Files <span class="count">{ itoa(len(p.Files)) }</span><kbd aria-hidden="true">g f</kbd> | |
| 433 | + | Files <span class="count">{ itoa(len(p.Files)) }</span><kbd aria-hidden="true">l</kbd> | |
| 434 | 434 | <button type="button" class="btn icon fold" data-js aria-expanded="true" title="fold the list of files" hx-on:click="ermiteMR.foldFiles()"> | |
| 435 | 435 | <span class="ico i-chevron" aria-hidden="true"></span><span class="sr">fold the list of files</span> | |
| 436 | 436 | </button> | |
| @@ -430,7 +430,7 @@ templ mrFooter(p MRPage) { | |||||
| 430 | templ mrRail(p MRPage) { | 430 | templ mrRail(p MRPage) { | ||
| 431 | <section aria-labelledby="r-files" class="r-files"> | 431 | <section aria-labelledby="r-files" class="r-files"> | ||
| 432 | <h2 id="r-files"> | 432 | <h2 id="r-files"> | ||
| 433 | - | Files <span class="count">{ itoa(len(p.Files)) }</span><kbd aria-hidden="true">g f</kbd> | 433 | + | Files <span class="count">{ itoa(len(p.Files)) }</span><kbd aria-hidden="true">l</kbd> |
| 434 | <button type="button" class="btn icon fold" data-js aria-expanded="true" title="fold the list of files" hx-on:click="ermiteMR.foldFiles()"> | 434 | <button type="button" class="btn icon fold" data-js aria-expanded="true" title="fold the list of files" hx-on:click="ermiteMR.foldFiles()"> | ||
| 435 | <span class="ico i-chevron" aria-hidden="true"></span><span class="sr">fold the list of files</span> | 435 | <span class="ico i-chevron" aria-hidden="true"></span><span class="sr">fold the list of files</span> | ||
| 436 | </button> | 436 | </button> | ||
M internal/adapters/web/mr_templ.go +1 -1 generated file: collapsed
M internal/adapters/web/mr_test.go +1 -1
| @@ -157,7 +157,7 @@ func TestMRPanelsAndMenus(t *testing.T) { | |||
| 157 | 157 | assert.Contains(t, footer, "more commits") | |
| 158 | 158 | assert.Contains(t, footer, "1/2 failed") | |
| 159 | 159 | rail := renderToString(t, mrRail(p)) | |
| 160 | - | assert.Contains(t, rail, "g f") | |
| 160 | + | assert.Contains(t, rail, `<kbd aria-hidden="true">l</kbd>`) | |
| 161 | 161 | for _, text := range []string{"Checks", "Commits", "Settings", "mr-checks"} { | |
| 162 | 162 | assert.NotContains(t, rail, text) | |
| 163 | 163 | } | |
| @@ -157,7 +157,7 @@ func TestMRPanelsAndMenus(t *testing.T) { | |||||
| 157 | assert.Contains(t, footer, "more commits") | 157 | assert.Contains(t, footer, "more commits") | ||
| 158 | assert.Contains(t, footer, "1/2 failed") | 158 | assert.Contains(t, footer, "1/2 failed") | ||
| 159 | rail := renderToString(t, mrRail(p)) | 159 | rail := renderToString(t, mrRail(p)) | ||
| 160 | - | assert.Contains(t, rail, "g f") | 160 | + | assert.Contains(t, rail, `<kbd aria-hidden="true">l</kbd>`) |
| 161 | for _, text := range []string{"Checks", "Commits", "Settings", "mr-checks"} { | 161 | for _, text := range []string{"Checks", "Commits", "Settings", "mr-checks"} { | ||
| 162 | assert.NotContains(t, rail, text) | 162 | assert.NotContains(t, rail, text) | ||
| 163 | } | 163 | } | ||
M internal/adapters/web/overlays.templ +2 -2
| @@ -26,7 +26,7 @@ templ OverlayHelp(mr bool) { | |||
| 26 | 26 | <div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div> | |
| 27 | 27 | <div><dt><kbd>/</kbd></dt><dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd></div> | |
| 28 | 28 | <div><dt><kbd>b</kbd></dt><dd>{ "switch" } branch or tag</dd></div> | |
| 29 | - | <div><dt><kbd>s</kbd> <kbd>t</kbd> <kbd>c</kbd> <kbd>r</kbd> <kbd>m</kbd> <kbd>i</kbd></dt><dd>tabs: summary, files, commits, branches & tags, merge requests, issues</dd></div> | |
| 29 | + | <div><dt><kbd>g s</kbd> <kbd>g f</kbd> <kbd>g c</kbd> <kbd>g b</kbd> <kbd>g m</kbd> <kbd>g i</kbd> <kbd>g r</kbd> <kbd>g a</kbd></dt><dd>tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)</dd></div> | |
| 30 | 30 | if SignedIn(ctx) { | |
| 31 | 31 | <div><dt><kbd>I</kbd></dt><dd>inbox</dd></div> | |
| 32 | 32 | } | |
| @@ -37,7 +37,7 @@ templ OverlayHelp(mr bool) { | |||
| 37 | 37 | <div><dt><kbd>e</kbd> <kbd>E</kbd></dt><dd>diff: the whole file in view / every file, with the lines the hunks hide</dd></div> | |
| 38 | 38 | <div><dt><kbd>n</kbd></dt><dd>merge request: next note in the diff</dd></div> | |
| 39 | 39 | if mr { | |
| 40 | - | <div><dt><kbd>g f</kbd></dt><dd>merge request: the list of files (j k move, enter opens, esc back)</dd></div> | |
| 40 | + | <div><dt><kbd>l</kbd></dt><dd>merge request: the list of files (j k move, enter opens, esc back)</dd></div> | |
| 41 | 41 | <div><dt><kbd>M</kbd></dt><dd>merge request: the merge menu; there 1–3 pick the mode, D deletes the branch, enter merges</dd></div> | |
| 42 | 42 | <div><dt><kbd>R</kbd></dt><dd>merge request: mark the head read</dd></div> | |
| 43 | 43 | } | |
| @@ -26,7 +26,7 @@ templ OverlayHelp(mr bool) { | |||||
| 26 | <div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div> | 26 | <div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div> | ||
| 27 | <div><dt><kbd>/</kbd></dt><dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd></div> | 27 | <div><dt><kbd>/</kbd></dt><dd>filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)</dd></div> | ||
| 28 | <div><dt><kbd>b</kbd></dt><dd>{ "switch" } branch or tag</dd></div> | 28 | <div><dt><kbd>b</kbd></dt><dd>{ "switch" } branch or tag</dd></div> | ||
| 29 | - | <div><dt><kbd>s</kbd> <kbd>t</kbd> <kbd>c</kbd> <kbd>r</kbd> <kbd>m</kbd> <kbd>i</kbd></dt><dd>tabs: summary, files, commits, branches & tags, merge requests, issues</dd></div> | 29 | + | <div><dt><kbd>g s</kbd> <kbd>g f</kbd> <kbd>g c</kbd> <kbd>g b</kbd> <kbd>g m</kbd> <kbd>g i</kbd> <kbd>g r</kbd> <kbd>g a</kbd></dt><dd>tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)</dd></div> |
| 30 | if SignedIn(ctx) { | 30 | if SignedIn(ctx) { | ||
| 31 | <div><dt><kbd>I</kbd></dt><dd>inbox</dd></div> | 31 | <div><dt><kbd>I</kbd></dt><dd>inbox</dd></div> | ||
| 32 | } | 32 | } | ||
| @@ -37,7 +37,7 @@ templ OverlayHelp(mr bool) { | |||||
| 37 | <div><dt><kbd>e</kbd> <kbd>E</kbd></dt><dd>diff: the whole file in view / every file, with the lines the hunks hide</dd></div> | 37 | <div><dt><kbd>e</kbd> <kbd>E</kbd></dt><dd>diff: the whole file in view / every file, with the lines the hunks hide</dd></div> | ||
| 38 | <div><dt><kbd>n</kbd></dt><dd>merge request: next note in the diff</dd></div> | 38 | <div><dt><kbd>n</kbd></dt><dd>merge request: next note in the diff</dd></div> | ||
| 39 | if mr { | 39 | if mr { | ||
| 40 | - | <div><dt><kbd>g f</kbd></dt><dd>merge request: the list of files (j k move, enter opens, esc back)</dd></div> | 40 | + | <div><dt><kbd>l</kbd></dt><dd>merge request: the list of files (j k move, enter opens, esc back)</dd></div> |
| 41 | <div><dt><kbd>M</kbd></dt><dd>merge request: the merge menu; there 1–3 pick the mode, D deletes the branch, enter merges</dd></div> | 41 | <div><dt><kbd>M</kbd></dt><dd>merge request: the merge menu; there 1–3 pick the mode, D deletes the branch, enter merges</dd></div> | ||
| 42 | <div><dt><kbd>R</kbd></dt><dd>merge request: mark the head read</dd></div> | 42 | <div><dt><kbd>R</kbd></dt><dd>merge request: mark the head read</dd></div> | ||
| 43 | } | 43 | } | ||
M internal/adapters/web/overlays_templ.go +2 -2 generated file: collapsed
M internal/adapters/web/pages.templ +8 -0
| @@ -115,6 +115,14 @@ templ summaryRail(p SummaryPage) { | |||
| 115 | 115 | if p.Latest != nil { | |
| 116 | 116 | @latestTagFact(*p.Latest) | |
| 117 | 117 | } | |
| 118 | + | if r := p.Release; r != nil { | |
| 119 | + | <dt>release</dt> | |
| 120 | + | <dd> | |
| 121 | + | <a href={ templ.SafeURL(r.Href) }>{ r.Tag }</a>{ " · " } | |
| 122 | + | <time datetime={ r.WhenAt } title={ r.WhenAt }>{ r.When }</time>{ " · " } | |
| 123 | + | <a href={ templ.SafeURL(r.AllHref) }>all releases</a> | |
| 124 | + | </dd> | |
| 125 | + | } | |
| 118 | 126 | </dl> | |
| 119 | 127 | </section> | |
| 120 | 128 | if len(p.Recent) > 0 { | |
| @@ -115,6 +115,14 @@ templ summaryRail(p SummaryPage) { | |||||
| 115 | if p.Latest != nil { | 115 | if p.Latest != nil { | ||
| 116 | @latestTagFact(*p.Latest) | 116 | @latestTagFact(*p.Latest) | ||
| 117 | } | 117 | } | ||
| 118 | + | if r := p.Release; r != nil { | |||
| 119 | + | <dt>release</dt> | |||
| 120 | + | <dd> | |||
| 121 | + | <a href={ templ.SafeURL(r.Href) }>{ r.Tag }</a>{ " · " } | |||
| 122 | + | <time datetime={ r.WhenAt } title={ r.WhenAt }>{ r.When }</time>{ " · " } | |||
| 123 | + | <a href={ templ.SafeURL(r.AllHref) }>all releases</a> | |||
| 124 | + | </dd> | |||
| 125 | + | } | |||
| 118 | </dl> | 126 | </dl> | ||
| 119 | </section> | 127 | </section> | ||
| 120 | if len(p.Recent) > 0 { | 128 | if len(p.Recent) > 0 { | ||
M internal/adapters/web/pages_templ.go +371 -261
| @@ -534,25 +534,135 @@ func summaryRail(p SummaryPage) templ.Component { | |||
| 534 | 534 | return templ_7745c5c3_Err | |
| 535 | 535 | } | |
| 536 | 536 | } | |
| 537 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</dl></section>") | |
| 537 | + | if r := p.Release; r != nil { | |
| 538 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<dt>release</dt><dd><a href=\"") | |
| 539 | + | if templ_7745c5c3_Err != nil { | |
| 540 | + | return templ_7745c5c3_Err | |
| 541 | + | } | |
| 542 | + | var templ_7745c5c3_Var27 templ.SafeURL | |
| 543 | + | templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href)) | |
| 544 | + | if templ_7745c5c3_Err != nil { | |
| 545 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 36} | |
| 546 | + | } | |
| 547 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | |
| 548 | + | if templ_7745c5c3_Err != nil { | |
| 549 | + | return templ_7745c5c3_Err | |
| 550 | + | } | |
| 551 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">") | |
| 552 | + | if templ_7745c5c3_Err != nil { | |
| 553 | + | return templ_7745c5c3_Err | |
| 554 | + | } | |
| 555 | + | var templ_7745c5c3_Var28 string | |
| 556 | + | templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(r.Tag) | |
| 557 | + | if templ_7745c5c3_Err != nil { | |
| 558 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 46} | |
| 559 | + | } | |
| 560 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) | |
| 561 | + | if templ_7745c5c3_Err != nil { | |
| 562 | + | return templ_7745c5c3_Err | |
| 563 | + | } | |
| 564 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</a>") | |
| 565 | + | if templ_7745c5c3_Err != nil { | |
| 566 | + | return templ_7745c5c3_Err | |
| 567 | + | } | |
| 568 | + | var templ_7745c5c3_Var29 string | |
| 569 | + | templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(" · ") | |
| 570 | + | if templ_7745c5c3_Err != nil { | |
| 571 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 60} | |
| 572 | + | } | |
| 573 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | |
| 574 | + | if templ_7745c5c3_Err != nil { | |
| 575 | + | return templ_7745c5c3_Err | |
| 576 | + | } | |
| 577 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " <time datetime=\"") | |
| 578 | + | if templ_7745c5c3_Err != nil { | |
| 579 | + | return templ_7745c5c3_Err | |
| 580 | + | } | |
| 581 | + | var templ_7745c5c3_Var30 string | |
| 582 | + | templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |
| 583 | + | if templ_7745c5c3_Err != nil { | |
| 584 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 30} | |
| 585 | + | } | |
| 586 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var30) | |
| 587 | + | if templ_7745c5c3_Err != nil { | |
| 588 | + | return templ_7745c5c3_Err | |
| 589 | + | } | |
| 590 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "\" title=\"") | |
| 591 | + | if templ_7745c5c3_Err != nil { | |
| 592 | + | return templ_7745c5c3_Err | |
| 593 | + | } | |
| 594 | + | var templ_7745c5c3_Var31 string | |
| 595 | + | templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |
| 596 | + | if templ_7745c5c3_Err != nil { | |
| 597 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 49} | |
| 598 | + | } | |
| 599 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var31) | |
| 600 | + | if templ_7745c5c3_Err != nil { | |
| 601 | + | return templ_7745c5c3_Err | |
| 602 | + | } | |
| 603 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\">") | |
| 604 | + | if templ_7745c5c3_Err != nil { | |
| 605 | + | return templ_7745c5c3_Err | |
| 606 | + | } | |
| 607 | + | var templ_7745c5c3_Var32 string | |
| 608 | + | templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(r.When) | |
| 609 | + | if templ_7745c5c3_Err != nil { | |
| 610 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 60} | |
| 611 | + | } | |
| 612 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) | |
| 613 | + | if templ_7745c5c3_Err != nil { | |
| 614 | + | return templ_7745c5c3_Err | |
| 615 | + | } | |
| 616 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</time>") | |
| 617 | + | if templ_7745c5c3_Err != nil { | |
| 618 | + | return templ_7745c5c3_Err | |
| 619 | + | } | |
| 620 | + | var templ_7745c5c3_Var33 string | |
| 621 | + | templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(" · ") | |
| 622 | + | if templ_7745c5c3_Err != nil { | |
| 623 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 77} | |
| 624 | + | } | |
| 625 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) | |
| 626 | + | if templ_7745c5c3_Err != nil { | |
| 627 | + | return templ_7745c5c3_Err | |
| 628 | + | } | |
| 629 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, " <a href=\"") | |
| 630 | + | if templ_7745c5c3_Err != nil { | |
| 631 | + | return templ_7745c5c3_Err | |
| 632 | + | } | |
| 633 | + | var templ_7745c5c3_Var34 templ.SafeURL | |
| 634 | + | templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.AllHref)) | |
| 635 | + | if templ_7745c5c3_Err != nil { | |
| 636 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 123, Col: 39} | |
| 637 | + | } | |
| 638 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) | |
| 639 | + | if templ_7745c5c3_Err != nil { | |
| 640 | + | return templ_7745c5c3_Err | |
| 641 | + | } | |
| 642 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\">all releases</a></dd>") | |
| 643 | + | if templ_7745c5c3_Err != nil { | |
| 644 | + | return templ_7745c5c3_Err | |
| 645 | + | } | |
| 646 | + | } | |
| 647 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</dl></section>") | |
| 538 | 648 | if templ_7745c5c3_Err != nil { | |
| 539 | 649 | return templ_7745c5c3_Err | |
| 540 | 650 | } | |
| 541 | 651 | if len(p.Recent) > 0 { | |
| 542 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"") | |
| 652 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"") | |
| 543 | 653 | if templ_7745c5c3_Err != nil { | |
| 544 | 654 | return templ_7745c5c3_Err | |
| 545 | 655 | } | |
| 546 | - | var templ_7745c5c3_Var27 templ.SafeURL | |
| 547 | - | templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref)) | |
| 656 | + | var templ_7745c5c3_Var35 templ.SafeURL | |
| 657 | + | templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref)) | |
| 548 | 658 | if templ_7745c5c3_Err != nil { | |
| 549 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 105} | |
| 659 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 129, Col: 105} | |
| 550 | 660 | } | |
| 551 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | |
| 661 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35)) | |
| 552 | 662 | if templ_7745c5c3_Err != nil { | |
| 553 | 663 | return templ_7745c5c3_Err | |
| 554 | 664 | } | |
| 555 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "\">View all</a></h2>") | |
| 665 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\">View all</a></h2>") | |
| 556 | 666 | if templ_7745c5c3_Err != nil { | |
| 557 | 667 | return templ_7745c5c3_Err | |
| 558 | 668 | } | |
| @@ -560,7 +670,7 @@ func summaryRail(p SummaryPage) templ.Component { | |||
| 560 | 670 | if templ_7745c5c3_Err != nil { | |
| 561 | 671 | return templ_7745c5c3_Err | |
| 562 | 672 | } | |
| 563 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</section>") | |
| 673 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</section>") | |
| 564 | 674 | if templ_7745c5c3_Err != nil { | |
| 565 | 675 | return templ_7745c5c3_Err | |
| 566 | 676 | } | |
| @@ -572,7 +682,7 @@ func summaryRail(p SummaryPage) templ.Component { | |||
| 572 | 682 | } | |
| 573 | 683 | } | |
| 574 | 684 | if len(p.Outline) > 0 && p.Readme != nil { | |
| 575 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>") | |
| 685 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>") | |
| 576 | 686 | if templ_7745c5c3_Err != nil { | |
| 577 | 687 | return templ_7745c5c3_Err | |
| 578 | 688 | } | |
| @@ -580,7 +690,7 @@ func summaryRail(p SummaryPage) templ.Component { | |||
| 580 | 690 | if templ_7745c5c3_Err != nil { | |
| 581 | 691 | return templ_7745c5c3_Err | |
| 582 | 692 | } | |
| 583 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</section>") | |
| 693 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</section>") | |
| 584 | 694 | if templ_7745c5c3_Err != nil { | |
| 585 | 695 | return templ_7745c5c3_Err | |
| 586 | 696 | } | |
| @@ -606,12 +716,12 @@ func Refs(l Layout, p RefsPage) templ.Component { | |||
| 606 | 716 | }() | |
| 607 | 717 | } | |
| 608 | 718 | ctx = templ.InitializeContext(ctx) | |
| 609 | - | templ_7745c5c3_Var28 := templ.GetChildren(ctx) | |
| 610 | - | if templ_7745c5c3_Var28 == nil { | |
| 611 | - | templ_7745c5c3_Var28 = templ.NopComponent | |
| 719 | + | templ_7745c5c3_Var36 := templ.GetChildren(ctx) | |
| 720 | + | if templ_7745c5c3_Var36 == nil { | |
| 721 | + | templ_7745c5c3_Var36 = templ.NopComponent | |
| 612 | 722 | } | |
| 613 | 723 | ctx = templ.ClearChildren(ctx) | |
| 614 | - | templ_7745c5c3_Var29 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 724 | + | templ_7745c5c3_Var37 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 615 | 725 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | |
| 616 | 726 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | |
| 617 | 727 | if !templ_7745c5c3_IsBuffer { | |
| @@ -623,7 +733,7 @@ func Refs(l Layout, p RefsPage) templ.Component { | |||
| 623 | 733 | }() | |
| 624 | 734 | } | |
| 625 | 735 | ctx = templ.InitializeContext(ctx) | |
| 626 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>") | |
| 736 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>") | |
| 627 | 737 | if templ_7745c5c3_Err != nil { | |
| 628 | 738 | return templ_7745c5c3_Err | |
| 629 | 739 | } | |
| @@ -631,32 +741,32 @@ func Refs(l Layout, p RefsPage) templ.Component { | |||
| 631 | 741 | if templ_7745c5c3_Err != nil { | |
| 632 | 742 | return templ_7745c5c3_Err | |
| 633 | 743 | } | |
| 634 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</table>") | |
| 744 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</table>") | |
| 635 | 745 | if templ_7745c5c3_Err != nil { | |
| 636 | 746 | return templ_7745c5c3_Err | |
| 637 | 747 | } | |
| 638 | 748 | if p.Note != "" { | |
| 639 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<p class=\"note\">") | |
| 749 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<p class=\"note\">") | |
| 640 | 750 | if templ_7745c5c3_Err != nil { | |
| 641 | 751 | return templ_7745c5c3_Err | |
| 642 | 752 | } | |
| 643 | - | var templ_7745c5c3_Var30 string | |
| 644 | - | templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note) | |
| 753 | + | var templ_7745c5c3_Var38 string | |
| 754 | + | templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note) | |
| 645 | 755 | if templ_7745c5c3_Err != nil { | |
| 646 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 154, Col: 27} | |
| 756 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 162, Col: 27} | |
| 647 | 757 | } | |
| 648 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) | |
| 758 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) | |
| 649 | 759 | if templ_7745c5c3_Err != nil { | |
| 650 | 760 | return templ_7745c5c3_Err | |
| 651 | 761 | } | |
| 652 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</p>") | |
| 762 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</p>") | |
| 653 | 763 | if templ_7745c5c3_Err != nil { | |
| 654 | 764 | return templ_7745c5c3_Err | |
| 655 | 765 | } | |
| 656 | 766 | } | |
| 657 | 767 | return nil | |
| 658 | 768 | }) | |
| 659 | - | templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var29), templ_7745c5c3_Buffer) | |
| 769 | + | templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var37), templ_7745c5c3_Buffer) | |
| 660 | 770 | if templ_7745c5c3_Err != nil { | |
| 661 | 771 | return templ_7745c5c3_Err | |
| 662 | 772 | } | |
| @@ -680,112 +790,112 @@ func refRow(kind string, r RefRow) templ.Component { | |||
| 680 | 790 | }() | |
| 681 | 791 | } | |
| 682 | 792 | ctx = templ.InitializeContext(ctx) | |
| 683 | - | templ_7745c5c3_Var31 := templ.GetChildren(ctx) | |
| 684 | - | if templ_7745c5c3_Var31 == nil { | |
| 685 | - | templ_7745c5c3_Var31 = templ.NopComponent | |
| 793 | + | templ_7745c5c3_Var39 := templ.GetChildren(ctx) | |
| 794 | + | if templ_7745c5c3_Var39 == nil { | |
| 795 | + | templ_7745c5c3_Var39 = templ.NopComponent | |
| 686 | 796 | } | |
| 687 | 797 | ctx = templ.ClearChildren(ctx) | |
| 688 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<tr") | |
| 798 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<tr") | |
| 689 | 799 | if templ_7745c5c3_Err != nil { | |
| 690 | 800 | return templ_7745c5c3_Err | |
| 691 | 801 | } | |
| 692 | 802 | if r.Cursor { | |
| 693 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, " data-cursor") | |
| 803 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " data-cursor") | |
| 694 | 804 | if templ_7745c5c3_Err != nil { | |
| 695 | 805 | return templ_7745c5c3_Err | |
| 696 | 806 | } | |
| 697 | 807 | } | |
| 698 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "><td class=\"c-kind mute\">") | |
| 808 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "><td class=\"c-kind mute\">") | |
| 699 | 809 | if templ_7745c5c3_Err != nil { | |
| 700 | 810 | return templ_7745c5c3_Err | |
| 701 | 811 | } | |
| 702 | - | var templ_7745c5c3_Var32 string | |
| 703 | - | templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(kind) | |
| 812 | + | var templ_7745c5c3_Var40 string | |
| 813 | + | templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(kind) | |
| 704 | 814 | if templ_7745c5c3_Err != nil { | |
| 705 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 161, Col: 32} | |
| 815 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 169, Col: 32} | |
| 706 | 816 | } | |
| 707 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) | |
| 817 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40)) | |
| 708 | 818 | if templ_7745c5c3_Err != nil { | |
| 709 | 819 | return templ_7745c5c3_Err | |
| 710 | 820 | } | |
| 711 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</td><td class=\"c-name\"><a href=\"") | |
| 821 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-name\"><a href=\"") | |
| 712 | 822 | if templ_7745c5c3_Err != nil { | |
| 713 | 823 | return templ_7745c5c3_Err | |
| 714 | 824 | } | |
| 715 | - | var templ_7745c5c3_Var33 templ.SafeURL | |
| 716 | - | templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href)) | |
| 825 | + | var templ_7745c5c3_Var41 templ.SafeURL | |
| 826 | + | templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href)) | |
| 717 | 827 | if templ_7745c5c3_Err != nil { | |
| 718 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 34} | |
| 828 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 34} | |
| 719 | 829 | } | |
| 720 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) | |
| 830 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41)) | |
| 721 | 831 | if templ_7745c5c3_Err != nil { | |
| 722 | 832 | return templ_7745c5c3_Err | |
| 723 | 833 | } | |
| 724 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\">") | |
| 834 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "\">") | |
| 725 | 835 | if templ_7745c5c3_Err != nil { | |
| 726 | 836 | return templ_7745c5c3_Err | |
| 727 | 837 | } | |
| 728 | - | var templ_7745c5c3_Var34 string | |
| 729 | - | templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) | |
| 838 | + | var templ_7745c5c3_Var42 string | |
| 839 | + | templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) | |
| 730 | 840 | if templ_7745c5c3_Err != nil { | |
| 731 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 45} | |
| 841 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 45} | |
| 732 | 842 | } | |
| 733 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) | |
| 843 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42)) | |
| 734 | 844 | if templ_7745c5c3_Err != nil { | |
| 735 | 845 | return templ_7745c5c3_Err | |
| 736 | 846 | } | |
| 737 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</a> ") | |
| 847 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "</a> ") | |
| 738 | 848 | if templ_7745c5c3_Err != nil { | |
| 739 | 849 | return templ_7745c5c3_Err | |
| 740 | 850 | } | |
| 741 | 851 | if r.Default { | |
| 742 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<span class=\"pill\">default</span>") | |
| 852 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "<span class=\"pill\">default</span>") | |
| 743 | 853 | if templ_7745c5c3_Err != nil { | |
| 744 | 854 | return templ_7745c5c3_Err | |
| 745 | 855 | } | |
| 746 | 856 | } | |
| 747 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "</td><td class=\"c-sha\">") | |
| 857 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</td><td class=\"c-sha\">") | |
| 748 | 858 | if templ_7745c5c3_Err != nil { | |
| 749 | 859 | return templ_7745c5c3_Err | |
| 750 | 860 | } | |
| 751 | 861 | if r.CHref != "" { | |
| 752 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<a href=\"") | |
| 862 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<a href=\"") | |
| 753 | 863 | if templ_7745c5c3_Err != nil { | |
| 754 | 864 | return templ_7745c5c3_Err | |
| 755 | 865 | } | |
| 756 | - | var templ_7745c5c3_Var35 templ.SafeURL | |
| 757 | - | templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref)) | |
| 866 | + | var templ_7745c5c3_Var43 templ.SafeURL | |
| 867 | + | templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref)) | |
| 758 | 868 | if templ_7745c5c3_Err != nil { | |
| 759 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 36} | |
| 869 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 36} | |
| 760 | 870 | } | |
| 761 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35)) | |
| 871 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43)) | |
| 762 | 872 | if templ_7745c5c3_Err != nil { | |
| 763 | 873 | return templ_7745c5c3_Err | |
| 764 | 874 | } | |
| 765 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\">") | |
| 875 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\">") | |
| 766 | 876 | if templ_7745c5c3_Err != nil { | |
| 767 | 877 | return templ_7745c5c3_Err | |
| 768 | 878 | } | |
| 769 | - | var templ_7745c5c3_Var36 string | |
| 770 | - | templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) | |
| 879 | + | var templ_7745c5c3_Var44 string | |
| 880 | + | templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) | |
| 771 | 881 | if templ_7745c5c3_Err != nil { | |
| 772 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 48} | |
| 882 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 48} | |
| 773 | 883 | } | |
| 774 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36)) | |
| 884 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44)) | |
| 775 | 885 | if templ_7745c5c3_Err != nil { | |
| 776 | 886 | return templ_7745c5c3_Err | |
| 777 | 887 | } | |
| 778 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "</a>") | |
| 888 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</a>") | |
| 779 | 889 | if templ_7745c5c3_Err != nil { | |
| 780 | 890 | return templ_7745c5c3_Err | |
| 781 | 891 | } | |
| 782 | 892 | } else { | |
| 783 | - | var templ_7745c5c3_Var37 string | |
| 784 | - | templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) | |
| 893 | + | var templ_7745c5c3_Var45 string | |
| 894 | + | templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) | |
| 785 | 895 | if templ_7745c5c3_Err != nil { | |
| 786 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 172, Col: 13} | |
| 896 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 180, Col: 13} | |
| 787 | 897 | } | |
| 788 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37)) | |
| 898 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45)) | |
| 789 | 899 | if templ_7745c5c3_Err != nil { | |
| 790 | 900 | return templ_7745c5c3_Err | |
| 791 | 901 | } | |
| @@ -794,69 +904,69 @@ func refRow(kind string, r RefRow) templ.Component { | |||
| 794 | 904 | if templ_7745c5c3_Err != nil { | |
| 795 | 905 | return templ_7745c5c3_Err | |
| 796 | 906 | } | |
| 797 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "</td><td class=\"c-sub\">") | |
| 907 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "</td><td class=\"c-sub\">") | |
| 798 | 908 | if templ_7745c5c3_Err != nil { | |
| 799 | 909 | return templ_7745c5c3_Err | |
| 800 | 910 | } | |
| 801 | - | var templ_7745c5c3_Var38 string | |
| 802 | - | templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject) | |
| 911 | + | var templ_7745c5c3_Var46 string | |
| 912 | + | templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject) | |
| 803 | 913 | if templ_7745c5c3_Err != nil { | |
| 804 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 176, Col: 31} | |
| 914 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 184, Col: 31} | |
| 805 | 915 | } | |
| 806 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) | |
| 916 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46)) | |
| 807 | 917 | if templ_7745c5c3_Err != nil { | |
| 808 | 918 | return templ_7745c5c3_Err | |
| 809 | 919 | } | |
| 810 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-when dim\">") | |
| 920 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</td><td class=\"c-when dim\">") | |
| 811 | 921 | if templ_7745c5c3_Err != nil { | |
| 812 | 922 | return templ_7745c5c3_Err | |
| 813 | 923 | } | |
| 814 | 924 | if r.WhenAt != "" { | |
| 815 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "<time datetime=\"") | |
| 925 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<time datetime=\"") | |
| 816 | 926 | if templ_7745c5c3_Err != nil { | |
| 817 | 927 | return templ_7745c5c3_Err | |
| 818 | 928 | } | |
| 819 | - | var templ_7745c5c3_Var39 string | |
| 820 | - | templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |
| 929 | + | var templ_7745c5c3_Var47 string | |
| 930 | + | templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |
| 821 | 931 | if templ_7745c5c3_Err != nil { | |
| 822 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 29} | |
| 932 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 29} | |
| 823 | 933 | } | |
| 824 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39) | |
| 934 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var47) | |
| 825 | 935 | if templ_7745c5c3_Err != nil { | |
| 826 | 936 | return templ_7745c5c3_Err | |
| 827 | 937 | } | |
| 828 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "\" title=\"") | |
| 938 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" title=\"") | |
| 829 | 939 | if templ_7745c5c3_Err != nil { | |
| 830 | 940 | return templ_7745c5c3_Err | |
| 831 | 941 | } | |
| 832 | - | var templ_7745c5c3_Var40 string | |
| 833 | - | templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |
| 942 | + | var templ_7745c5c3_Var48 string | |
| 943 | + | templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |
| 834 | 944 | if templ_7745c5c3_Err != nil { | |
| 835 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 48} | |
| 945 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 48} | |
| 836 | 946 | } | |
| 837 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40) | |
| 947 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var48) | |
| 838 | 948 | if templ_7745c5c3_Err != nil { | |
| 839 | 949 | return templ_7745c5c3_Err | |
| 840 | 950 | } | |
| 841 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\">") | |
| 951 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\">") | |
| 842 | 952 | if templ_7745c5c3_Err != nil { | |
| 843 | 953 | return templ_7745c5c3_Err | |
| 844 | 954 | } | |
| 845 | - | var templ_7745c5c3_Var41 string | |
| 846 | - | templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(r.When) | |
| 955 | + | var templ_7745c5c3_Var49 string | |
| 956 | + | templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(r.When) | |
| 847 | 957 | if templ_7745c5c3_Err != nil { | |
| 848 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 59} | |
| 958 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 59} | |
| 849 | 959 | } | |
| 850 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41)) | |
| 960 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49)) | |
| 851 | 961 | if templ_7745c5c3_Err != nil { | |
| 852 | 962 | return templ_7745c5c3_Err | |
| 853 | 963 | } | |
| 854 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</time>") | |
| 964 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</time>") | |
| 855 | 965 | if templ_7745c5c3_Err != nil { | |
| 856 | 966 | return templ_7745c5c3_Err | |
| 857 | 967 | } | |
| 858 | 968 | } | |
| 859 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "</td></tr>") | |
| 969 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</td></tr>") | |
| 860 | 970 | if templ_7745c5c3_Err != nil { | |
| 861 | 971 | return templ_7745c5c3_Err | |
| 862 | 972 | } | |
| @@ -880,12 +990,12 @@ func refsRail(p RefsPage) templ.Component { | |||
| 880 | 990 | }() | |
| 881 | 991 | } | |
| 882 | 992 | ctx = templ.InitializeContext(ctx) | |
| 883 | - | templ_7745c5c3_Var42 := templ.GetChildren(ctx) | |
| 884 | - | if templ_7745c5c3_Var42 == nil { | |
| 885 | - | templ_7745c5c3_Var42 = templ.NopComponent | |
| 993 | + | templ_7745c5c3_Var50 := templ.GetChildren(ctx) | |
| 994 | + | if templ_7745c5c3_Var50 == nil { | |
| 995 | + | templ_7745c5c3_Var50 = templ.NopComponent | |
| 886 | 996 | } | |
| 887 | 997 | ctx = templ.ClearChildren(ctx) | |
| 888 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>") | |
| 998 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>") | |
| 889 | 999 | if templ_7745c5c3_Err != nil { | |
| 890 | 1000 | return templ_7745c5c3_Err | |
| 891 | 1001 | } | |
| @@ -893,7 +1003,7 @@ func refsRail(p RefsPage) templ.Component { | |||
| 893 | 1003 | if templ_7745c5c3_Err != nil { | |
| 894 | 1004 | return templ_7745c5c3_Err | |
| 895 | 1005 | } | |
| 896 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</section>") | |
| 1006 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</section>") | |
| 897 | 1007 | if templ_7745c5c3_Err != nil { | |
| 898 | 1008 | return templ_7745c5c3_Err | |
| 899 | 1009 | } | |
| @@ -918,12 +1028,12 @@ func State(l Layout, p StatePage) templ.Component { | |||
| 918 | 1028 | }() | |
| 919 | 1029 | } | |
| 920 | 1030 | ctx = templ.InitializeContext(ctx) | |
| 921 | - | templ_7745c5c3_Var43 := templ.GetChildren(ctx) | |
| 922 | - | if templ_7745c5c3_Var43 == nil { | |
| 923 | - | templ_7745c5c3_Var43 = templ.NopComponent | |
| 1031 | + | templ_7745c5c3_Var51 := templ.GetChildren(ctx) | |
| 1032 | + | if templ_7745c5c3_Var51 == nil { | |
| 1033 | + | templ_7745c5c3_Var51 = templ.NopComponent | |
| 924 | 1034 | } | |
| 925 | 1035 | ctx = templ.ClearChildren(ctx) | |
| 926 | - | templ_7745c5c3_Var44 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1036 | + | templ_7745c5c3_Var52 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 927 | 1037 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | |
| 928 | 1038 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | |
| 929 | 1039 | if !templ_7745c5c3_IsBuffer { | |
| @@ -935,51 +1045,51 @@ func State(l Layout, p StatePage) templ.Component { | |||
| 935 | 1045 | }() | |
| 936 | 1046 | } | |
| 937 | 1047 | ctx = templ.InitializeContext(ctx) | |
| 938 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">") | |
| 1048 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">") | |
| 939 | 1049 | if templ_7745c5c3_Err != nil { | |
| 940 | 1050 | return templ_7745c5c3_Err | |
| 941 | 1051 | } | |
| 942 | - | var templ_7745c5c3_Var45 string | |
| 943 | - | templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code) | |
| 1052 | + | var templ_7745c5c3_Var53 string | |
| 1053 | + | templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code) | |
| 944 | 1054 | if templ_7745c5c3_Err != nil { | |
| 945 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 196, Col: 30} | |
| 1055 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 204, Col: 30} | |
| 946 | 1056 | } | |
| 947 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45)) | |
| 1057 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53)) | |
| 948 | 1058 | if templ_7745c5c3_Err != nil { | |
| 949 | 1059 | return templ_7745c5c3_Err | |
| 950 | 1060 | } | |
| 951 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</p><h1 id=\"state-title\">") | |
| 1061 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "</p><h1 id=\"state-title\">") | |
| 952 | 1062 | if templ_7745c5c3_Err != nil { | |
| 953 | 1063 | return templ_7745c5c3_Err | |
| 954 | 1064 | } | |
| 955 | - | var templ_7745c5c3_Var46 string | |
| 956 | - | templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | |
| 1065 | + | var templ_7745c5c3_Var54 string | |
| 1066 | + | templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | |
| 957 | 1067 | if templ_7745c5c3_Err != nil { | |
| 958 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 197, Col: 33} | |
| 1068 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 205, Col: 33} | |
| 959 | 1069 | } | |
| 960 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46)) | |
| 1070 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54)) | |
| 961 | 1071 | if templ_7745c5c3_Err != nil { | |
| 962 | 1072 | return templ_7745c5c3_Err | |
| 963 | 1073 | } | |
| 964 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "</h1>") | |
| 1074 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>") | |
| 965 | 1075 | if templ_7745c5c3_Err != nil { | |
| 966 | 1076 | return templ_7745c5c3_Err | |
| 967 | 1077 | } | |
| 968 | 1078 | for _, line := range p.Lines { | |
| 969 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "<p class=\"dim\">") | |
| 1079 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">") | |
| 970 | 1080 | if templ_7745c5c3_Err != nil { | |
| 971 | 1081 | return templ_7745c5c3_Err | |
| 972 | 1082 | } | |
| 973 | - | var templ_7745c5c3_Var47 string | |
| 974 | - | templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(line) | |
| 1083 | + | var templ_7745c5c3_Var55 string | |
| 1084 | + | templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(line) | |
| 975 | 1085 | if templ_7745c5c3_Err != nil { | |
| 976 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 199, Col: 25} | |
| 1086 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 207, Col: 25} | |
| 977 | 1087 | } | |
| 978 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47)) | |
| 1088 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55)) | |
| 979 | 1089 | if templ_7745c5c3_Err != nil { | |
| 980 | 1090 | return templ_7745c5c3_Err | |
| 981 | 1091 | } | |
| 982 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</p>") | |
| 1092 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>") | |
| 983 | 1093 | if templ_7745c5c3_Err != nil { | |
| 984 | 1094 | return templ_7745c5c3_Err | |
| 985 | 1095 | } | |
| @@ -990,49 +1100,49 @@ func State(l Layout, p StatePage) templ.Component { | |||
| 990 | 1100 | return templ_7745c5c3_Err | |
| 991 | 1101 | } | |
| 992 | 1102 | } | |
| 993 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<p class=\"state-back\">") | |
| 1103 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<p class=\"state-back\">") | |
| 994 | 1104 | if templ_7745c5c3_Err != nil { | |
| 995 | 1105 | return templ_7745c5c3_Err | |
| 996 | 1106 | } | |
| 997 | 1107 | for _, b := range p.Back { | |
| 998 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<a href=\"") | |
| 1108 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "<a href=\"") | |
| 999 | 1109 | if templ_7745c5c3_Err != nil { | |
| 1000 | 1110 | return templ_7745c5c3_Err | |
| 1001 | 1111 | } | |
| 1002 | - | var templ_7745c5c3_Var48 templ.SafeURL | |
| 1003 | - | templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href)) | |
| 1112 | + | var templ_7745c5c3_Var56 templ.SafeURL | |
| 1113 | + | templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href)) | |
| 1004 | 1114 | if templ_7745c5c3_Err != nil { | |
| 1005 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 36} | |
| 1115 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 36} | |
| 1006 | 1116 | } | |
| 1007 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48)) | |
| 1117 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56)) | |
| 1008 | 1118 | if templ_7745c5c3_Err != nil { | |
| 1009 | 1119 | return templ_7745c5c3_Err | |
| 1010 | 1120 | } | |
| 1011 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "\">") | |
| 1121 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "\">") | |
| 1012 | 1122 | if templ_7745c5c3_Err != nil { | |
| 1013 | 1123 | return templ_7745c5c3_Err | |
| 1014 | 1124 | } | |
| 1015 | - | var templ_7745c5c3_Var49 string | |
| 1016 | - | templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label) | |
| 1125 | + | var templ_7745c5c3_Var57 string | |
| 1126 | + | templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label) | |
| 1017 | 1127 | if templ_7745c5c3_Err != nil { | |
| 1018 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 48} | |
| 1128 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 48} | |
| 1019 | 1129 | } | |
| 1020 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49)) | |
| 1130 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57)) | |
| 1021 | 1131 | if templ_7745c5c3_Err != nil { | |
| 1022 | 1132 | return templ_7745c5c3_Err | |
| 1023 | 1133 | } | |
| 1024 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</a>") | |
| 1134 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</a>") | |
| 1025 | 1135 | if templ_7745c5c3_Err != nil { | |
| 1026 | 1136 | return templ_7745c5c3_Err | |
| 1027 | 1137 | } | |
| 1028 | 1138 | } | |
| 1029 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "</p></section>") | |
| 1139 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</p></section>") | |
| 1030 | 1140 | if templ_7745c5c3_Err != nil { | |
| 1031 | 1141 | return templ_7745c5c3_Err | |
| 1032 | 1142 | } | |
| 1033 | 1143 | return nil | |
| 1034 | 1144 | }) | |
| 1035 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var44), templ_7745c5c3_Buffer) | |
| 1145 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var52), templ_7745c5c3_Buffer) | |
| 1036 | 1146 | if templ_7745c5c3_Err != nil { | |
| 1037 | 1147 | return templ_7745c5c3_Err | |
| 1038 | 1148 | } | |
| @@ -1061,12 +1171,12 @@ func Login(l Layout, p LoginPage) templ.Component { | |||
| 1061 | 1171 | }() | |
| 1062 | 1172 | } | |
| 1063 | 1173 | ctx = templ.InitializeContext(ctx) | |
| 1064 | - | templ_7745c5c3_Var50 := templ.GetChildren(ctx) | |
| 1065 | - | if templ_7745c5c3_Var50 == nil { | |
| 1066 | - | templ_7745c5c3_Var50 = templ.NopComponent | |
| 1174 | + | templ_7745c5c3_Var58 := templ.GetChildren(ctx) | |
| 1175 | + | if templ_7745c5c3_Var58 == nil { | |
| 1176 | + | templ_7745c5c3_Var58 = templ.NopComponent | |
| 1067 | 1177 | } | |
| 1068 | 1178 | ctx = templ.ClearChildren(ctx) | |
| 1069 | - | templ_7745c5c3_Var51 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1179 | + | templ_7745c5c3_Var59 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1070 | 1180 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | |
| 1071 | 1181 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | |
| 1072 | 1182 | if !templ_7745c5c3_IsBuffer { | |
| @@ -1078,75 +1188,75 @@ func Login(l Layout, p LoginPage) templ.Component { | |||
| 1078 | 1188 | }() | |
| 1079 | 1189 | } | |
| 1080 | 1190 | ctx = templ.InitializeContext(ctx) | |
| 1081 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") | |
| 1191 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") | |
| 1082 | 1192 | if templ_7745c5c3_Err != nil { | |
| 1083 | 1193 | return templ_7745c5c3_Err | |
| 1084 | 1194 | } | |
| 1085 | - | var templ_7745c5c3_Var52 string | |
| 1086 | - | templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | |
| 1195 | + | var templ_7745c5c3_Var60 string | |
| 1196 | + | templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | |
| 1087 | 1197 | if templ_7745c5c3_Err != nil { | |
| 1088 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 221, Col: 33} | |
| 1198 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 229, Col: 33} | |
| 1089 | 1199 | } | |
| 1090 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52)) | |
| 1200 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60)) | |
| 1091 | 1201 | if templ_7745c5c3_Err != nil { | |
| 1092 | 1202 | return templ_7745c5c3_Err | |
| 1093 | 1203 | } | |
| 1094 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>") | |
| 1204 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</h1>") | |
| 1095 | 1205 | if templ_7745c5c3_Err != nil { | |
| 1096 | 1206 | return templ_7745c5c3_Err | |
| 1097 | 1207 | } | |
| 1098 | 1208 | for _, line := range p.Lines { | |
| 1099 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">") | |
| 1209 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "<p class=\"dim\">") | |
| 1100 | 1210 | if templ_7745c5c3_Err != nil { | |
| 1101 | 1211 | return templ_7745c5c3_Err | |
| 1102 | 1212 | } | |
| 1103 | - | var templ_7745c5c3_Var53 string | |
| 1104 | - | templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(line) | |
| 1213 | + | var templ_7745c5c3_Var61 string | |
| 1214 | + | templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(line) | |
| 1105 | 1215 | if templ_7745c5c3_Err != nil { | |
| 1106 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 223, Col: 25} | |
| 1216 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 231, Col: 25} | |
| 1107 | 1217 | } | |
| 1108 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53)) | |
| 1218 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61)) | |
| 1109 | 1219 | if templ_7745c5c3_Err != nil { | |
| 1110 | 1220 | return templ_7745c5c3_Err | |
| 1111 | 1221 | } | |
| 1112 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>") | |
| 1222 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</p>") | |
| 1113 | 1223 | if templ_7745c5c3_Err != nil { | |
| 1114 | 1224 | return templ_7745c5c3_Err | |
| 1115 | 1225 | } | |
| 1116 | 1226 | } | |
| 1117 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<form class=\"state-act\" method=\"post\" action=\"") | |
| 1227 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<form class=\"state-act\" method=\"post\" action=\"") | |
| 1118 | 1228 | if templ_7745c5c3_Err != nil { | |
| 1119 | 1229 | return templ_7745c5c3_Err | |
| 1120 | 1230 | } | |
| 1121 | - | var templ_7745c5c3_Var54 templ.SafeURL | |
| 1122 | - | templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action)) | |
| 1231 | + | var templ_7745c5c3_Var62 templ.SafeURL | |
| 1232 | + | templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action)) | |
| 1123 | 1233 | if templ_7745c5c3_Err != nil { | |
| 1124 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 225, Col: 73} | |
| 1234 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 233, Col: 73} | |
| 1125 | 1235 | } | |
| 1126 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54)) | |
| 1236 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) | |
| 1127 | 1237 | if templ_7745c5c3_Err != nil { | |
| 1128 | 1238 | return templ_7745c5c3_Err | |
| 1129 | 1239 | } | |
| 1130 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">") | |
| 1240 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">") | |
| 1131 | 1241 | if templ_7745c5c3_Err != nil { | |
| 1132 | 1242 | return templ_7745c5c3_Err | |
| 1133 | 1243 | } | |
| 1134 | - | var templ_7745c5c3_Var55 string | |
| 1135 | - | templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) | |
| 1244 | + | var templ_7745c5c3_Var63 string | |
| 1245 | + | templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) | |
| 1136 | 1246 | if templ_7745c5c3_Err != nil { | |
| 1137 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 226, Col: 56} | |
| 1247 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 234, Col: 56} | |
| 1138 | 1248 | } | |
| 1139 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55)) | |
| 1249 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63)) | |
| 1140 | 1250 | if templ_7745c5c3_Err != nil { | |
| 1141 | 1251 | return templ_7745c5c3_Err | |
| 1142 | 1252 | } | |
| 1143 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") | |
| 1253 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") | |
| 1144 | 1254 | if templ_7745c5c3_Err != nil { | |
| 1145 | 1255 | return templ_7745c5c3_Err | |
| 1146 | 1256 | } | |
| 1147 | 1257 | return nil | |
| 1148 | 1258 | }) | |
| 1149 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var51), templ_7745c5c3_Buffer) | |
| 1259 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var59), templ_7745c5c3_Buffer) | |
| 1150 | 1260 | if templ_7745c5c3_Err != nil { | |
| 1151 | 1261 | return templ_7745c5c3_Err | |
| 1152 | 1262 | } | |
| @@ -1172,12 +1282,12 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component { | |||
| 1172 | 1282 | }() | |
| 1173 | 1283 | } | |
| 1174 | 1284 | ctx = templ.InitializeContext(ctx) | |
| 1175 | - | templ_7745c5c3_Var56 := templ.GetChildren(ctx) | |
| 1176 | - | if templ_7745c5c3_Var56 == nil { | |
| 1177 | - | templ_7745c5c3_Var56 = templ.NopComponent | |
| 1285 | + | templ_7745c5c3_Var64 := templ.GetChildren(ctx) | |
| 1286 | + | if templ_7745c5c3_Var64 == nil { | |
| 1287 | + | templ_7745c5c3_Var64 = templ.NopComponent | |
| 1178 | 1288 | } | |
| 1179 | 1289 | ctx = templ.ClearChildren(ctx) | |
| 1180 | - | templ_7745c5c3_Var57 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1290 | + | templ_7745c5c3_Var65 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1181 | 1291 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | |
| 1182 | 1292 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | |
| 1183 | 1293 | if !templ_7745c5c3_IsBuffer { | |
| @@ -1189,88 +1299,88 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component { | |||
| 1189 | 1299 | }() | |
| 1190 | 1300 | } | |
| 1191 | 1301 | ctx = templ.InitializeContext(ctx) | |
| 1192 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") | |
| 1302 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") | |
| 1193 | 1303 | if templ_7745c5c3_Err != nil { | |
| 1194 | 1304 | return templ_7745c5c3_Err | |
| 1195 | 1305 | } | |
| 1196 | - | var templ_7745c5c3_Var58 string | |
| 1197 | - | templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | |
| 1306 | + | var templ_7745c5c3_Var66 string | |
| 1307 | + | templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | |
| 1198 | 1308 | if templ_7745c5c3_Err != nil { | |
| 1199 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 238, Col: 33} | |
| 1309 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 246, Col: 33} | |
| 1200 | 1310 | } | |
| 1201 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58)) | |
| 1311 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) | |
| 1202 | 1312 | if templ_7745c5c3_Err != nil { | |
| 1203 | 1313 | return templ_7745c5c3_Err | |
| 1204 | 1314 | } | |
| 1205 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"") | |
| 1315 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"") | |
| 1206 | 1316 | if templ_7745c5c3_Err != nil { | |
| 1207 | 1317 | return templ_7745c5c3_Err | |
| 1208 | 1318 | } | |
| 1209 | - | var templ_7745c5c3_Var59 string | |
| 1210 | - | templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) | |
| 1319 | + | var templ_7745c5c3_Var67 string | |
| 1320 | + | templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) | |
| 1211 | 1321 | if templ_7745c5c3_Err != nil { | |
| 1212 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 87} | |
| 1322 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 87} | |
| 1213 | 1323 | } | |
| 1214 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59) | |
| 1324 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67) | |
| 1215 | 1325 | if templ_7745c5c3_Err != nil { | |
| 1216 | 1326 | return templ_7745c5c3_Err | |
| 1217 | 1327 | } | |
| 1218 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "\" data-finish=\"") | |
| 1328 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "\" data-finish=\"") | |
| 1219 | 1329 | if templ_7745c5c3_Err != nil { | |
| 1220 | 1330 | return templ_7745c5c3_Err | |
| 1221 | 1331 | } | |
| 1222 | - | var templ_7745c5c3_Var60 string | |
| 1223 | - | templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) | |
| 1332 | + | var templ_7745c5c3_Var68 string | |
| 1333 | + | templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) | |
| 1224 | 1334 | if templ_7745c5c3_Err != nil { | |
| 1225 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 112} | |
| 1335 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 112} | |
| 1226 | 1336 | } | |
| 1227 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60) | |
| 1337 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var68) | |
| 1228 | 1338 | if templ_7745c5c3_Err != nil { | |
| 1229 | 1339 | return templ_7745c5c3_Err | |
| 1230 | 1340 | } | |
| 1231 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">") | |
| 1341 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\">") | |
| 1232 | 1342 | if templ_7745c5c3_Err != nil { | |
| 1233 | 1343 | return templ_7745c5c3_Err | |
| 1234 | 1344 | } | |
| 1235 | - | var templ_7745c5c3_Var61 string | |
| 1236 | - | templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) | |
| 1345 | + | var templ_7745c5c3_Var69 string | |
| 1346 | + | templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) | |
| 1237 | 1347 | if templ_7745c5c3_Err != nil { | |
| 1238 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 125} | |
| 1348 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 125} | |
| 1239 | 1349 | } | |
| 1240 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61)) | |
| 1350 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69)) | |
| 1241 | 1351 | if templ_7745c5c3_Err != nil { | |
| 1242 | 1352 | return templ_7745c5c3_Err | |
| 1243 | 1353 | } | |
| 1244 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") | |
| 1354 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") | |
| 1245 | 1355 | if templ_7745c5c3_Err != nil { | |
| 1246 | 1356 | return templ_7745c5c3_Err | |
| 1247 | 1357 | } | |
| 1248 | 1358 | for _, line := range p.Lines { | |
| 1249 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<p class=\"dim\">") | |
| 1359 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "<p class=\"dim\">") | |
| 1250 | 1360 | if templ_7745c5c3_Err != nil { | |
| 1251 | 1361 | return templ_7745c5c3_Err | |
| 1252 | 1362 | } | |
| 1253 | - | var templ_7745c5c3_Var62 string | |
| 1254 | - | templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(line) | |
| 1363 | + | var templ_7745c5c3_Var70 string | |
| 1364 | + | templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(line) | |
| 1255 | 1365 | if templ_7745c5c3_Err != nil { | |
| 1256 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 244, Col: 25} | |
| 1366 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 252, Col: 25} | |
| 1257 | 1367 | } | |
| 1258 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) | |
| 1368 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70)) | |
| 1259 | 1369 | if templ_7745c5c3_Err != nil { | |
| 1260 | 1370 | return templ_7745c5c3_Err | |
| 1261 | 1371 | } | |
| 1262 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "</p>") | |
| 1372 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "</p>") | |
| 1263 | 1373 | if templ_7745c5c3_Err != nil { | |
| 1264 | 1374 | return templ_7745c5c3_Err | |
| 1265 | 1375 | } | |
| 1266 | 1376 | } | |
| 1267 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") | |
| 1377 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") | |
| 1268 | 1378 | if templ_7745c5c3_Err != nil { | |
| 1269 | 1379 | return templ_7745c5c3_Err | |
| 1270 | 1380 | } | |
| 1271 | 1381 | return nil | |
| 1272 | 1382 | }) | |
| 1273 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var57), templ_7745c5c3_Buffer) | |
| 1383 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var65), templ_7745c5c3_Buffer) | |
| 1274 | 1384 | if templ_7745c5c3_Err != nil { | |
| 1275 | 1385 | return templ_7745c5c3_Err | |
| 1276 | 1386 | } | |
| @@ -1295,12 +1405,12 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component { | |||
| 1295 | 1405 | }() | |
| 1296 | 1406 | } | |
| 1297 | 1407 | ctx = templ.InitializeContext(ctx) | |
| 1298 | - | templ_7745c5c3_Var63 := templ.GetChildren(ctx) | |
| 1299 | - | if templ_7745c5c3_Var63 == nil { | |
| 1300 | - | templ_7745c5c3_Var63 = templ.NopComponent | |
| 1408 | + | templ_7745c5c3_Var71 := templ.GetChildren(ctx) | |
| 1409 | + | if templ_7745c5c3_Var71 == nil { | |
| 1410 | + | templ_7745c5c3_Var71 = templ.NopComponent | |
| 1301 | 1411 | } | |
| 1302 | 1412 | ctx = templ.ClearChildren(ctx) | |
| 1303 | - | templ_7745c5c3_Var64 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1413 | + | templ_7745c5c3_Var72 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | |
| 1304 | 1414 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | |
| 1305 | 1415 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | |
| 1306 | 1416 | if !templ_7745c5c3_IsBuffer { | |
| @@ -1312,231 +1422,231 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component { | |||
| 1312 | 1422 | }() | |
| 1313 | 1423 | } | |
| 1314 | 1424 | ctx = templ.InitializeContext(ctx) | |
| 1315 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">") | |
| 1425 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">") | |
| 1316 | 1426 | if templ_7745c5c3_Err != nil { | |
| 1317 | 1427 | return templ_7745c5c3_Err | |
| 1318 | 1428 | } | |
| 1319 | - | var templ_7745c5c3_Var65 string | |
| 1320 | - | templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows))) | |
| 1429 | + | var templ_7745c5c3_Var73 string | |
| 1430 | + | templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows))) | |
| 1321 | 1431 | if templ_7745c5c3_Err != nil { | |
| 1322 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 254, Col: 81} | |
| 1432 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 262, Col: 81} | |
| 1323 | 1433 | } | |
| 1324 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65)) | |
| 1434 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73)) | |
| 1325 | 1435 | if templ_7745c5c3_Err != nil { | |
| 1326 | 1436 | return templ_7745c5c3_Err | |
| 1327 | 1437 | } | |
| 1328 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>") | |
| 1438 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>") | |
| 1329 | 1439 | if templ_7745c5c3_Err != nil { | |
| 1330 | 1440 | return templ_7745c5c3_Err | |
| 1331 | 1441 | } | |
| 1332 | 1442 | if len(p.Rows) > 0 { | |
| 1333 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>") | |
| 1443 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>") | |
| 1334 | 1444 | if templ_7745c5c3_Err != nil { | |
| 1335 | 1445 | return templ_7745c5c3_Err | |
| 1336 | 1446 | } | |
| 1337 | 1447 | for _, r := range p.Rows { | |
| 1338 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "<tr><td class=\"c-name\">") | |
| 1448 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "<tr><td class=\"c-name\">") | |
| 1339 | 1449 | if templ_7745c5c3_Err != nil { | |
| 1340 | 1450 | return templ_7745c5c3_Err | |
| 1341 | 1451 | } | |
| 1342 | - | var templ_7745c5c3_Var66 string | |
| 1343 | - | templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) | |
| 1452 | + | var templ_7745c5c3_Var74 string | |
| 1453 | + | templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) | |
| 1344 | 1454 | if templ_7745c5c3_Err != nil { | |
| 1345 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 270, Col: 34} | |
| 1455 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 278, Col: 34} | |
| 1346 | 1456 | } | |
| 1347 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) | |
| 1457 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74)) | |
| 1348 | 1458 | if templ_7745c5c3_Err != nil { | |
| 1349 | 1459 | return templ_7745c5c3_Err | |
| 1350 | 1460 | } | |
| 1351 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</td><td class=\"c-when nowrap\"><time") | |
| 1461 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</td><td class=\"c-when nowrap\"><time") | |
| 1352 | 1462 | if templ_7745c5c3_Err != nil { | |
| 1353 | 1463 | return templ_7745c5c3_Err | |
| 1354 | 1464 | } | |
| 1355 | 1465 | if r.CreatedAt != "" { | |
| 1356 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " datetime=\"") | |
| 1466 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, " datetime=\"") | |
| 1357 | 1467 | if templ_7745c5c3_Err != nil { | |
| 1358 | 1468 | return templ_7745c5c3_Err | |
| 1359 | 1469 | } | |
| 1360 | - | var templ_7745c5c3_Var67 string | |
| 1361 | - | templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt) | |
| 1470 | + | var templ_7745c5c3_Var75 string | |
| 1471 | + | templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt) | |
| 1362 | 1472 | if templ_7745c5c3_Err != nil { | |
| 1363 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 274, Col: 32} | |
| 1473 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 282, Col: 32} | |
| 1364 | 1474 | } | |
| 1365 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67) | |
| 1475 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75) | |
| 1366 | 1476 | if templ_7745c5c3_Err != nil { | |
| 1367 | 1477 | return templ_7745c5c3_Err | |
| 1368 | 1478 | } | |
| 1369 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"") | |
| 1479 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "\"") | |
| 1370 | 1480 | if templ_7745c5c3_Err != nil { | |
| 1371 | 1481 | return templ_7745c5c3_Err | |
| 1372 | 1482 | } | |
| 1373 | 1483 | } | |
| 1374 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, ">") | |
| 1484 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, ">") | |
| 1375 | 1485 | if templ_7745c5c3_Err != nil { | |
| 1376 | 1486 | return templ_7745c5c3_Err | |
| 1377 | 1487 | } | |
| 1378 | - | var templ_7745c5c3_Var68 string | |
| 1379 | - | templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created) | |
| 1488 | + | var templ_7745c5c3_Var76 string | |
| 1489 | + | templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created) | |
| 1380 | 1490 | if templ_7745c5c3_Err != nil { | |
| 1381 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 276, Col: 20} | |
| 1491 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 284, Col: 20} | |
| 1382 | 1492 | } | |
| 1383 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68)) | |
| 1493 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76)) | |
| 1384 | 1494 | if templ_7745c5c3_Err != nil { | |
| 1385 | 1495 | return templ_7745c5c3_Err | |
| 1386 | 1496 | } | |
| 1387 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "</time></td><td class=\"c-when nowrap\"><time") | |
| 1497 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "</time></td><td class=\"c-when nowrap\"><time") | |
| 1388 | 1498 | if templ_7745c5c3_Err != nil { | |
| 1389 | 1499 | return templ_7745c5c3_Err | |
| 1390 | 1500 | } | |
| 1391 | 1501 | if r.LastUsedAt != "" { | |
| 1392 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " datetime=\"") | |
| 1502 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, " datetime=\"") | |
| 1393 | 1503 | if templ_7745c5c3_Err != nil { | |
| 1394 | 1504 | return templ_7745c5c3_Err | |
| 1395 | 1505 | } | |
| 1396 | - | var templ_7745c5c3_Var69 string | |
| 1397 | - | templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt) | |
| 1506 | + | var templ_7745c5c3_Var77 string | |
| 1507 | + | templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt) | |
| 1398 | 1508 | if templ_7745c5c3_Err != nil { | |
| 1399 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 281, Col: 33} | |
| 1509 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 289, Col: 33} | |
| 1400 | 1510 | } | |
| 1401 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var69) | |
| 1511 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77) | |
| 1402 | 1512 | if templ_7745c5c3_Err != nil { | |
| 1403 | 1513 | return templ_7745c5c3_Err | |
| 1404 | 1514 | } | |
| 1405 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"") | |
| 1515 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "\"") | |
| 1406 | 1516 | if templ_7745c5c3_Err != nil { | |
| 1407 | 1517 | return templ_7745c5c3_Err | |
| 1408 | 1518 | } | |
| 1409 | 1519 | } | |
| 1410 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, ">") | |
| 1520 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, ">") | |
| 1411 | 1521 | if templ_7745c5c3_Err != nil { | |
| 1412 | 1522 | return templ_7745c5c3_Err | |
| 1413 | 1523 | } | |
| 1414 | - | var templ_7745c5c3_Var70 string | |
| 1415 | - | templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed) | |
| 1524 | + | var templ_7745c5c3_Var78 string | |
| 1525 | + | templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed) | |
| 1416 | 1526 | if templ_7745c5c3_Err != nil { | |
| 1417 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 283, Col: 21} | |
| 1527 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 291, Col: 21} | |
| 1418 | 1528 | } | |
| 1419 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70)) | |
| 1529 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78)) | |
| 1420 | 1530 | if templ_7745c5c3_Err != nil { | |
| 1421 | 1531 | return templ_7745c5c3_Err | |
| 1422 | 1532 | } | |
| 1423 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</time></td><td class=\"c-sync\">") | |
| 1533 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</time></td><td class=\"c-sync\">") | |
| 1424 | 1534 | if templ_7745c5c3_Err != nil { | |
| 1425 | 1535 | return templ_7745c5c3_Err | |
| 1426 | 1536 | } | |
| 1427 | 1537 | if r.Synced { | |
| 1428 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "yes") | |
| 1538 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "yes") | |
| 1429 | 1539 | if templ_7745c5c3_Err != nil { | |
| 1430 | 1540 | return templ_7745c5c3_Err | |
| 1431 | 1541 | } | |
| 1432 | 1542 | } else { | |
| 1433 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "no") | |
| 1543 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "no") | |
| 1434 | 1544 | if templ_7745c5c3_Err != nil { | |
| 1435 | 1545 | return templ_7745c5c3_Err | |
| 1436 | 1546 | } | |
| 1437 | 1547 | } | |
| 1438 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "</td><td class=\"c-act\"><form method=\"post\" action=\"") | |
| 1548 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "</td><td class=\"c-act\"><form method=\"post\" action=\"") | |
| 1439 | 1549 | if templ_7745c5c3_Err != nil { | |
| 1440 | 1550 | return templ_7745c5c3_Err | |
| 1441 | 1551 | } | |
| 1442 | - | var templ_7745c5c3_Var71 templ.SafeURL | |
| 1443 | - | templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove)) | |
| 1552 | + | var templ_7745c5c3_Var79 templ.SafeURL | |
| 1553 | + | templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove)) | |
| 1444 | 1554 | if templ_7745c5c3_Err != nil { | |
| 1445 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 293, Col: 60} | |
| 1555 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 301, Col: 60} | |
| 1446 | 1556 | } | |
| 1447 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71)) | |
| 1557 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79)) | |
| 1448 | 1558 | if templ_7745c5c3_Err != nil { | |
| 1449 | 1559 | return templ_7745c5c3_Err | |
| 1450 | 1560 | } | |
| 1451 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"") | |
| 1561 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"") | |
| 1452 | 1562 | if templ_7745c5c3_Err != nil { | |
| 1453 | 1563 | return templ_7745c5c3_Err | |
| 1454 | 1564 | } | |
| 1455 | - | var templ_7745c5c3_Var72 string | |
| 1456 | - | templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name) | |
| 1565 | + | var templ_7745c5c3_Var80 string | |
| 1566 | + | templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name) | |
| 1457 | 1567 | if templ_7745c5c3_Err != nil { | |
| 1458 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 294, Col: 89} | |
| 1568 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 302, Col: 89} | |
| 1459 | 1569 | } | |
| 1460 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72) | |
| 1570 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80) | |
| 1461 | 1571 | if templ_7745c5c3_Err != nil { | |
| 1462 | 1572 | return templ_7745c5c3_Err | |
| 1463 | 1573 | } | |
| 1464 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "\">Remove</button></form></td></tr>") | |
| 1574 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\">Remove</button></form></td></tr>") | |
| 1465 | 1575 | if templ_7745c5c3_Err != nil { | |
| 1466 | 1576 | return templ_7745c5c3_Err | |
| 1467 | 1577 | } | |
| 1468 | 1578 | } | |
| 1469 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "</tbody></table>") | |
| 1579 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "</tbody></table>") | |
| 1470 | 1580 | if templ_7745c5c3_Err != nil { | |
| 1471 | 1581 | return templ_7745c5c3_Err | |
| 1472 | 1582 | } | |
| 1473 | 1583 | } else { | |
| 1474 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "<p class=\"lede dim\">no passkeys yet.</p>") | |
| 1584 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<p class=\"lede dim\">no passkeys yet.</p>") | |
| 1475 | 1585 | if templ_7745c5c3_Err != nil { | |
| 1476 | 1586 | return templ_7745c5c3_Err | |
| 1477 | 1587 | } | |
| 1478 | 1588 | } | |
| 1479 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, " ") | |
| 1589 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, " ") | |
| 1480 | 1590 | if templ_7745c5c3_Err != nil { | |
| 1481 | 1591 | return templ_7745c5c3_Err | |
| 1482 | 1592 | } | |
| 1483 | 1593 | if p.Full { | |
| 1484 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "<p class=\"dim\">") | |
| 1594 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "<p class=\"dim\">") | |
| 1485 | 1595 | if templ_7745c5c3_Err != nil { | |
| 1486 | 1596 | return templ_7745c5c3_Err | |
| 1487 | 1597 | } | |
| 1488 | - | var templ_7745c5c3_Var73 string | |
| 1489 | - | templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max)) | |
| 1598 | + | var templ_7745c5c3_Var81 string | |
| 1599 | + | templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max)) | |
| 1490 | 1600 | if templ_7745c5c3_Err != nil { | |
| 1491 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 305, Col: 31} | |
| 1601 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 313, Col: 31} | |
| 1492 | 1602 | } | |
| 1493 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73)) | |
| 1603 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81)) | |
| 1494 | 1604 | if templ_7745c5c3_Err != nil { | |
| 1495 | 1605 | return templ_7745c5c3_Err | |
| 1496 | 1606 | } | |
| 1497 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, " passkeys are registered, the most there can be. Remove one to add another.</p>") | |
| 1607 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, " passkeys are registered, the most there can be. Remove one to add another.</p>") | |
| 1498 | 1608 | if templ_7745c5c3_Err != nil { | |
| 1499 | 1609 | return templ_7745c5c3_Err | |
| 1500 | 1610 | } | |
| 1501 | 1611 | } else { | |
| 1502 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"") | |
| 1612 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"") | |
| 1503 | 1613 | if templ_7745c5c3_Err != nil { | |
| 1504 | 1614 | return templ_7745c5c3_Err | |
| 1505 | 1615 | } | |
| 1506 | - | var templ_7745c5c3_Var74 string | |
| 1507 | - | templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) | |
| 1616 | + | var templ_7745c5c3_Var82 string | |
| 1617 | + | templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) | |
| 1508 | 1618 | if templ_7745c5c3_Err != nil { | |
| 1509 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 90} | |
| 1619 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 90} | |
| 1510 | 1620 | } | |
| 1511 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var74) | |
| 1621 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82) | |
| 1512 | 1622 | if templ_7745c5c3_Err != nil { | |
| 1513 | 1623 | return templ_7745c5c3_Err | |
| 1514 | 1624 | } | |
| 1515 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-finish=\"") | |
| 1625 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "\" data-finish=\"") | |
| 1516 | 1626 | if templ_7745c5c3_Err != nil { | |
| 1517 | 1627 | return templ_7745c5c3_Err | |
| 1518 | 1628 | } | |
| 1519 | - | var templ_7745c5c3_Var75 string | |
| 1520 | - | templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) | |
| 1629 | + | var templ_7745c5c3_Var83 string | |
| 1630 | + | templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) | |
| 1521 | 1631 | if templ_7745c5c3_Err != nil { | |
| 1522 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 115} | |
| 1632 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 115} | |
| 1523 | 1633 | } | |
| 1524 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75) | |
| 1634 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83) | |
| 1525 | 1635 | if templ_7745c5c3_Err != nil { | |
| 1526 | 1636 | return templ_7745c5c3_Err | |
| 1527 | 1637 | } | |
| 1528 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\">Add a passkey</button></form>") | |
| 1638 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "\">Add a passkey</button></form>") | |
| 1529 | 1639 | if templ_7745c5c3_Err != nil { | |
| 1530 | 1640 | return templ_7745c5c3_Err | |
| 1531 | 1641 | } | |
| 1532 | 1642 | } | |
| 1533 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") | |
| 1643 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") | |
| 1534 | 1644 | if templ_7745c5c3_Err != nil { | |
| 1535 | 1645 | return templ_7745c5c3_Err | |
| 1536 | 1646 | } | |
| 1537 | 1647 | return nil | |
| 1538 | 1648 | }) | |
| 1539 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var64), templ_7745c5c3_Buffer) | |
| 1649 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var72), templ_7745c5c3_Buffer) | |
| 1540 | 1650 | if templ_7745c5c3_Err != nil { | |
| 1541 | 1651 | return templ_7745c5c3_Err | |
| 1542 | 1652 | } | |
| @@ -534,25 +534,135 @@ func summaryRail(p SummaryPage) templ.Component { | |||||
| 534 | return templ_7745c5c3_Err | 534 | return templ_7745c5c3_Err | ||
| 535 | } | 535 | } | ||
| 536 | } | 536 | } | ||
| 537 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</dl></section>") | 537 | + | if r := p.Release; r != nil { |
| 538 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<dt>release</dt><dd><a href=\"") | |||
| 539 | + | if templ_7745c5c3_Err != nil { | |||
| 540 | + | return templ_7745c5c3_Err | |||
| 541 | + | } | |||
| 542 | + | var templ_7745c5c3_Var27 templ.SafeURL | |||
| 543 | + | templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href)) | |||
| 544 | + | if templ_7745c5c3_Err != nil { | |||
| 545 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 36} | |||
| 546 | + | } | |||
| 547 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | |||
| 548 | + | if templ_7745c5c3_Err != nil { | |||
| 549 | + | return templ_7745c5c3_Err | |||
| 550 | + | } | |||
| 551 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">") | |||
| 552 | + | if templ_7745c5c3_Err != nil { | |||
| 553 | + | return templ_7745c5c3_Err | |||
| 554 | + | } | |||
| 555 | + | var templ_7745c5c3_Var28 string | |||
| 556 | + | templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(r.Tag) | |||
| 557 | + | if templ_7745c5c3_Err != nil { | |||
| 558 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 46} | |||
| 559 | + | } | |||
| 560 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) | |||
| 561 | + | if templ_7745c5c3_Err != nil { | |||
| 562 | + | return templ_7745c5c3_Err | |||
| 563 | + | } | |||
| 564 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</a>") | |||
| 565 | + | if templ_7745c5c3_Err != nil { | |||
| 566 | + | return templ_7745c5c3_Err | |||
| 567 | + | } | |||
| 568 | + | var templ_7745c5c3_Var29 string | |||
| 569 | + | templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(" · ") | |||
| 570 | + | if templ_7745c5c3_Err != nil { | |||
| 571 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 60} | |||
| 572 | + | } | |||
| 573 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) | |||
| 574 | + | if templ_7745c5c3_Err != nil { | |||
| 575 | + | return templ_7745c5c3_Err | |||
| 576 | + | } | |||
| 577 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " <time datetime=\"") | |||
| 578 | + | if templ_7745c5c3_Err != nil { | |||
| 579 | + | return templ_7745c5c3_Err | |||
| 580 | + | } | |||
| 581 | + | var templ_7745c5c3_Var30 string | |||
| 582 | + | templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |||
| 583 | + | if templ_7745c5c3_Err != nil { | |||
| 584 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 30} | |||
| 585 | + | } | |||
| 586 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var30) | |||
| 587 | + | if templ_7745c5c3_Err != nil { | |||
| 588 | + | return templ_7745c5c3_Err | |||
| 589 | + | } | |||
| 590 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "\" title=\"") | |||
| 591 | + | if templ_7745c5c3_Err != nil { | |||
| 592 | + | return templ_7745c5c3_Err | |||
| 593 | + | } | |||
| 594 | + | var templ_7745c5c3_Var31 string | |||
| 595 | + | templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | |||
| 596 | + | if templ_7745c5c3_Err != nil { | |||
| 597 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 49} | |||
| 598 | + | } | |||
| 599 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var31) | |||
| 600 | + | if templ_7745c5c3_Err != nil { | |||
| 601 | + | return templ_7745c5c3_Err | |||
| 602 | + | } | |||
| 603 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\">") | |||
| 604 | + | if templ_7745c5c3_Err != nil { | |||
| 605 | + | return templ_7745c5c3_Err | |||
| 606 | + | } | |||
| 607 | + | var templ_7745c5c3_Var32 string | |||
| 608 | + | templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(r.When) | |||
| 609 | + | if templ_7745c5c3_Err != nil { | |||
| 610 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 60} | |||
| 611 | + | } | |||
| 612 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) | |||
| 613 | + | if templ_7745c5c3_Err != nil { | |||
| 614 | + | return templ_7745c5c3_Err | |||
| 615 | + | } | |||
| 616 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</time>") | |||
| 617 | + | if templ_7745c5c3_Err != nil { | |||
| 618 | + | return templ_7745c5c3_Err | |||
| 619 | + | } | |||
| 620 | + | var templ_7745c5c3_Var33 string | |||
| 621 | + | templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(" · ") | |||
| 622 | + | if templ_7745c5c3_Err != nil { | |||
| 623 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 122, Col: 77} | |||
| 624 | + | } | |||
| 625 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) | |||
| 626 | + | if templ_7745c5c3_Err != nil { | |||
| 627 | + | return templ_7745c5c3_Err | |||
| 628 | + | } | |||
| 629 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, " <a href=\"") | |||
| 630 | + | if templ_7745c5c3_Err != nil { | |||
| 631 | + | return templ_7745c5c3_Err | |||
| 632 | + | } | |||
| 633 | + | var templ_7745c5c3_Var34 templ.SafeURL | |||
| 634 | + | templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.AllHref)) | |||
| 635 | + | if templ_7745c5c3_Err != nil { | |||
| 636 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 123, Col: 39} | |||
| 637 | + | } | |||
| 638 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) | |||
| 639 | + | if templ_7745c5c3_Err != nil { | |||
| 640 | + | return templ_7745c5c3_Err | |||
| 641 | + | } | |||
| 642 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\">all releases</a></dd>") | |||
| 643 | + | if templ_7745c5c3_Err != nil { | |||
| 644 | + | return templ_7745c5c3_Err | |||
| 645 | + | } | |||
| 646 | + | } | |||
| 647 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</dl></section>") | |||
| 538 | if templ_7745c5c3_Err != nil { | 648 | if templ_7745c5c3_Err != nil { | ||
| 539 | return templ_7745c5c3_Err | 649 | return templ_7745c5c3_Err | ||
| 540 | } | 650 | } | ||
| 541 | if len(p.Recent) > 0 { | 651 | if len(p.Recent) > 0 { | ||
| 542 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"") | 652 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<section aria-labelledby=\"r-recent\"><h2 id=\"r-recent\">Recent commits <a href=\"") |
| 543 | if templ_7745c5c3_Err != nil { | 653 | if templ_7745c5c3_Err != nil { | ||
| 544 | return templ_7745c5c3_Err | 654 | return templ_7745c5c3_Err | ||
| 545 | } | 655 | } | ||
| 546 | - | var templ_7745c5c3_Var27 templ.SafeURL | 656 | + | var templ_7745c5c3_Var35 templ.SafeURL |
| 547 | - | templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref)) | 657 | + | templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.AllHref)) |
| 548 | if templ_7745c5c3_Err != nil { | 658 | if templ_7745c5c3_Err != nil { | ||
| 549 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 121, Col: 105} | 659 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 129, Col: 105} |
| 550 | } | 660 | } | ||
| 551 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) | 661 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35)) |
| 552 | if templ_7745c5c3_Err != nil { | 662 | if templ_7745c5c3_Err != nil { | ||
| 553 | return templ_7745c5c3_Err | 663 | return templ_7745c5c3_Err | ||
| 554 | } | 664 | } | ||
| 555 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "\">View all</a></h2>") | 665 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\">View all</a></h2>") |
| 556 | if templ_7745c5c3_Err != nil { | 666 | if templ_7745c5c3_Err != nil { | ||
| 557 | return templ_7745c5c3_Err | 667 | return templ_7745c5c3_Err | ||
| 558 | } | 668 | } | ||
| @@ -560,7 +670,7 @@ func summaryRail(p SummaryPage) templ.Component { | |||||
| 560 | if templ_7745c5c3_Err != nil { | 670 | if templ_7745c5c3_Err != nil { | ||
| 561 | return templ_7745c5c3_Err | 671 | return templ_7745c5c3_Err | ||
| 562 | } | 672 | } | ||
| 563 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</section>") | 673 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</section>") |
| 564 | if templ_7745c5c3_Err != nil { | 674 | if templ_7745c5c3_Err != nil { | ||
| 565 | return templ_7745c5c3_Err | 675 | return templ_7745c5c3_Err | ||
| 566 | } | 676 | } | ||
| @@ -572,7 +682,7 @@ func summaryRail(p SummaryPage) templ.Component { | |||||
| 572 | } | 682 | } | ||
| 573 | } | 683 | } | ||
| 574 | if len(p.Outline) > 0 && p.Readme != nil { | 684 | if len(p.Outline) > 0 && p.Readme != nil { | ||
| 575 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>") | 685 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "<section aria-labelledby=\"r-outline\"><h2 id=\"r-outline\">On this page</h2>") |
| 576 | if templ_7745c5c3_Err != nil { | 686 | if templ_7745c5c3_Err != nil { | ||
| 577 | return templ_7745c5c3_Err | 687 | return templ_7745c5c3_Err | ||
| 578 | } | 688 | } | ||
| @@ -580,7 +690,7 @@ func summaryRail(p SummaryPage) templ.Component { | |||||
| 580 | if templ_7745c5c3_Err != nil { | 690 | if templ_7745c5c3_Err != nil { | ||
| 581 | return templ_7745c5c3_Err | 691 | return templ_7745c5c3_Err | ||
| 582 | } | 692 | } | ||
| 583 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</section>") | 693 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</section>") |
| 584 | if templ_7745c5c3_Err != nil { | 694 | if templ_7745c5c3_Err != nil { | ||
| 585 | return templ_7745c5c3_Err | 695 | return templ_7745c5c3_Err | ||
| 586 | } | 696 | } | ||
| @@ -606,12 +716,12 @@ func Refs(l Layout, p RefsPage) templ.Component { | |||||
| 606 | }() | 716 | }() | ||
| 607 | } | 717 | } | ||
| 608 | ctx = templ.InitializeContext(ctx) | 718 | ctx = templ.InitializeContext(ctx) | ||
| 609 | - | templ_7745c5c3_Var28 := templ.GetChildren(ctx) | 719 | + | templ_7745c5c3_Var36 := templ.GetChildren(ctx) |
| 610 | - | if templ_7745c5c3_Var28 == nil { | 720 | + | if templ_7745c5c3_Var36 == nil { |
| 611 | - | templ_7745c5c3_Var28 = templ.NopComponent | 721 | + | templ_7745c5c3_Var36 = templ.NopComponent |
| 612 | } | 722 | } | ||
| 613 | ctx = templ.ClearChildren(ctx) | 723 | ctx = templ.ClearChildren(ctx) | ||
| 614 | - | templ_7745c5c3_Var29 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 724 | + | templ_7745c5c3_Var37 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { |
| 615 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | 725 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||
| 616 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | 726 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||
| 617 | if !templ_7745c5c3_IsBuffer { | 727 | if !templ_7745c5c3_IsBuffer { | ||
| @@ -623,7 +733,7 @@ func Refs(l Layout, p RefsPage) templ.Component { | |||||
| 623 | }() | 733 | }() | ||
| 624 | } | 734 | } | ||
| 625 | ctx = templ.InitializeContext(ctx) | 735 | ctx = templ.InitializeContext(ctx) | ||
| 626 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>") | 736 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<div class=\"filter\"><label for=\"ref-filter\" class=\"sr\">filter</label> <input id=\"ref-filter\" type=\"search\" data-filter=\"#ref-rows > tr\" placeholder=\"Filter branches and tags…\" autocomplete=\"off\" hx-on:input=\"ermite.filter(this)\"></div><table class=\"list refs\" aria-label=\"Branches and tags\"><thead><tr><th class=\"c-kind\">kind</th><th class=\"c-name\">name</th><th class=\"c-sha\">commit</th><th class=\"c-sub\">subject</th><th class=\"c-when\">date</th></tr></thead>") |
| 627 | if templ_7745c5c3_Err != nil { | 737 | if templ_7745c5c3_Err != nil { | ||
| 628 | return templ_7745c5c3_Err | 738 | return templ_7745c5c3_Err | ||
| 629 | } | 739 | } | ||
| @@ -631,32 +741,32 @@ func Refs(l Layout, p RefsPage) templ.Component { | |||||
| 631 | if templ_7745c5c3_Err != nil { | 741 | if templ_7745c5c3_Err != nil { | ||
| 632 | return templ_7745c5c3_Err | 742 | return templ_7745c5c3_Err | ||
| 633 | } | 743 | } | ||
| 634 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</table>") | 744 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</table>") |
| 635 | if templ_7745c5c3_Err != nil { | 745 | if templ_7745c5c3_Err != nil { | ||
| 636 | return templ_7745c5c3_Err | 746 | return templ_7745c5c3_Err | ||
| 637 | } | 747 | } | ||
| 638 | if p.Note != "" { | 748 | if p.Note != "" { | ||
| 639 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<p class=\"note\">") | 749 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<p class=\"note\">") |
| 640 | if templ_7745c5c3_Err != nil { | 750 | if templ_7745c5c3_Err != nil { | ||
| 641 | return templ_7745c5c3_Err | 751 | return templ_7745c5c3_Err | ||
| 642 | } | 752 | } | ||
| 643 | - | var templ_7745c5c3_Var30 string | 753 | + | var templ_7745c5c3_Var38 string |
| 644 | - | templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note) | 754 | + | templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(p.Note) |
| 645 | if templ_7745c5c3_Err != nil { | 755 | if templ_7745c5c3_Err != nil { | ||
| 646 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 154, Col: 27} | 756 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 162, Col: 27} |
| 647 | } | 757 | } | ||
| 648 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) | 758 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) |
| 649 | if templ_7745c5c3_Err != nil { | 759 | if templ_7745c5c3_Err != nil { | ||
| 650 | return templ_7745c5c3_Err | 760 | return templ_7745c5c3_Err | ||
| 651 | } | 761 | } | ||
| 652 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</p>") | 762 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</p>") |
| 653 | if templ_7745c5c3_Err != nil { | 763 | if templ_7745c5c3_Err != nil { | ||
| 654 | return templ_7745c5c3_Err | 764 | return templ_7745c5c3_Err | ||
| 655 | } | 765 | } | ||
| 656 | } | 766 | } | ||
| 657 | return nil | 767 | return nil | ||
| 658 | }) | 768 | }) | ||
| 659 | - | templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var29), templ_7745c5c3_Buffer) | 769 | + | templ_7745c5c3_Err = Shell(l, refsRail(p)).Render(templ.WithChildren(ctx, templ_7745c5c3_Var37), templ_7745c5c3_Buffer) |
| 660 | if templ_7745c5c3_Err != nil { | 770 | if templ_7745c5c3_Err != nil { | ||
| 661 | return templ_7745c5c3_Err | 771 | return templ_7745c5c3_Err | ||
| 662 | } | 772 | } | ||
| @@ -680,112 +790,112 @@ func refRow(kind string, r RefRow) templ.Component { | |||||
| 680 | }() | 790 | }() | ||
| 681 | } | 791 | } | ||
| 682 | ctx = templ.InitializeContext(ctx) | 792 | ctx = templ.InitializeContext(ctx) | ||
| 683 | - | templ_7745c5c3_Var31 := templ.GetChildren(ctx) | 793 | + | templ_7745c5c3_Var39 := templ.GetChildren(ctx) |
| 684 | - | if templ_7745c5c3_Var31 == nil { | 794 | + | if templ_7745c5c3_Var39 == nil { |
| 685 | - | templ_7745c5c3_Var31 = templ.NopComponent | 795 | + | templ_7745c5c3_Var39 = templ.NopComponent |
| 686 | } | 796 | } | ||
| 687 | ctx = templ.ClearChildren(ctx) | 797 | ctx = templ.ClearChildren(ctx) | ||
| 688 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "<tr") | 798 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<tr") |
| 689 | if templ_7745c5c3_Err != nil { | 799 | if templ_7745c5c3_Err != nil { | ||
| 690 | return templ_7745c5c3_Err | 800 | return templ_7745c5c3_Err | ||
| 691 | } | 801 | } | ||
| 692 | if r.Cursor { | 802 | if r.Cursor { | ||
| 693 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, " data-cursor") | 803 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " data-cursor") |
| 694 | if templ_7745c5c3_Err != nil { | 804 | if templ_7745c5c3_Err != nil { | ||
| 695 | return templ_7745c5c3_Err | 805 | return templ_7745c5c3_Err | ||
| 696 | } | 806 | } | ||
| 697 | } | 807 | } | ||
| 698 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "><td class=\"c-kind mute\">") | 808 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "><td class=\"c-kind mute\">") |
| 699 | if templ_7745c5c3_Err != nil { | 809 | if templ_7745c5c3_Err != nil { | ||
| 700 | return templ_7745c5c3_Err | 810 | return templ_7745c5c3_Err | ||
| 701 | } | 811 | } | ||
| 702 | - | var templ_7745c5c3_Var32 string | 812 | + | var templ_7745c5c3_Var40 string |
| 703 | - | templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(kind) | 813 | + | templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(kind) |
| 704 | if templ_7745c5c3_Err != nil { | 814 | if templ_7745c5c3_Err != nil { | ||
| 705 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 161, Col: 32} | 815 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 169, Col: 32} |
| 706 | } | 816 | } | ||
| 707 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) | 817 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40)) |
| 708 | if templ_7745c5c3_Err != nil { | 818 | if templ_7745c5c3_Err != nil { | ||
| 709 | return templ_7745c5c3_Err | 819 | return templ_7745c5c3_Err | ||
| 710 | } | 820 | } | ||
| 711 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</td><td class=\"c-name\"><a href=\"") | 821 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-name\"><a href=\"") |
| 712 | if templ_7745c5c3_Err != nil { | 822 | if templ_7745c5c3_Err != nil { | ||
| 713 | return templ_7745c5c3_Err | 823 | return templ_7745c5c3_Err | ||
| 714 | } | 824 | } | ||
| 715 | - | var templ_7745c5c3_Var33 templ.SafeURL | 825 | + | var templ_7745c5c3_Var41 templ.SafeURL |
| 716 | - | templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href)) | 826 | + | templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Href)) |
| 717 | if templ_7745c5c3_Err != nil { | 827 | if templ_7745c5c3_Err != nil { | ||
| 718 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 34} | 828 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 34} |
| 719 | } | 829 | } | ||
| 720 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) | 830 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41)) |
| 721 | if templ_7745c5c3_Err != nil { | 831 | if templ_7745c5c3_Err != nil { | ||
| 722 | return templ_7745c5c3_Err | 832 | return templ_7745c5c3_Err | ||
| 723 | } | 833 | } | ||
| 724 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\">") | 834 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "\">") |
| 725 | if templ_7745c5c3_Err != nil { | 835 | if templ_7745c5c3_Err != nil { | ||
| 726 | return templ_7745c5c3_Err | 836 | return templ_7745c5c3_Err | ||
| 727 | } | 837 | } | ||
| 728 | - | var templ_7745c5c3_Var34 string | 838 | + | var templ_7745c5c3_Var42 string |
| 729 | - | templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) | 839 | + | templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) |
| 730 | if templ_7745c5c3_Err != nil { | 840 | if templ_7745c5c3_Err != nil { | ||
| 731 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 163, Col: 45} | 841 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 171, Col: 45} |
| 732 | } | 842 | } | ||
| 733 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) | 843 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42)) |
| 734 | if templ_7745c5c3_Err != nil { | 844 | if templ_7745c5c3_Err != nil { | ||
| 735 | return templ_7745c5c3_Err | 845 | return templ_7745c5c3_Err | ||
| 736 | } | 846 | } | ||
| 737 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</a> ") | 847 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "</a> ") |
| 738 | if templ_7745c5c3_Err != nil { | 848 | if templ_7745c5c3_Err != nil { | ||
| 739 | return templ_7745c5c3_Err | 849 | return templ_7745c5c3_Err | ||
| 740 | } | 850 | } | ||
| 741 | if r.Default { | 851 | if r.Default { | ||
| 742 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<span class=\"pill\">default</span>") | 852 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "<span class=\"pill\">default</span>") |
| 743 | if templ_7745c5c3_Err != nil { | 853 | if templ_7745c5c3_Err != nil { | ||
| 744 | return templ_7745c5c3_Err | 854 | return templ_7745c5c3_Err | ||
| 745 | } | 855 | } | ||
| 746 | } | 856 | } | ||
| 747 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "</td><td class=\"c-sha\">") | 857 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</td><td class=\"c-sha\">") |
| 748 | if templ_7745c5c3_Err != nil { | 858 | if templ_7745c5c3_Err != nil { | ||
| 749 | return templ_7745c5c3_Err | 859 | return templ_7745c5c3_Err | ||
| 750 | } | 860 | } | ||
| 751 | if r.CHref != "" { | 861 | if r.CHref != "" { | ||
| 752 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "<a href=\"") | 862 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "<a href=\"") |
| 753 | if templ_7745c5c3_Err != nil { | 863 | if templ_7745c5c3_Err != nil { | ||
| 754 | return templ_7745c5c3_Err | 864 | return templ_7745c5c3_Err | ||
| 755 | } | 865 | } | ||
| 756 | - | var templ_7745c5c3_Var35 templ.SafeURL | 866 | + | var templ_7745c5c3_Var43 templ.SafeURL |
| 757 | - | templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref)) | 867 | + | templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.CHref)) |
| 758 | if templ_7745c5c3_Err != nil { | 868 | if templ_7745c5c3_Err != nil { | ||
| 759 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 36} | 869 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 36} |
| 760 | } | 870 | } | ||
| 761 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35)) | 871 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43)) |
| 762 | if templ_7745c5c3_Err != nil { | 872 | if templ_7745c5c3_Err != nil { | ||
| 763 | return templ_7745c5c3_Err | 873 | return templ_7745c5c3_Err | ||
| 764 | } | 874 | } | ||
| 765 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\">") | 875 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\">") |
| 766 | if templ_7745c5c3_Err != nil { | 876 | if templ_7745c5c3_Err != nil { | ||
| 767 | return templ_7745c5c3_Err | 877 | return templ_7745c5c3_Err | ||
| 768 | } | 878 | } | ||
| 769 | - | var templ_7745c5c3_Var36 string | 879 | + | var templ_7745c5c3_Var44 string |
| 770 | - | templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) | 880 | + | templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) |
| 771 | if templ_7745c5c3_Err != nil { | 881 | if templ_7745c5c3_Err != nil { | ||
| 772 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 170, Col: 48} | 882 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 178, Col: 48} |
| 773 | } | 883 | } | ||
| 774 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36)) | 884 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44)) |
| 775 | if templ_7745c5c3_Err != nil { | 885 | if templ_7745c5c3_Err != nil { | ||
| 776 | return templ_7745c5c3_Err | 886 | return templ_7745c5c3_Err | ||
| 777 | } | 887 | } | ||
| 778 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "</a>") | 888 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</a>") |
| 779 | if templ_7745c5c3_Err != nil { | 889 | if templ_7745c5c3_Err != nil { | ||
| 780 | return templ_7745c5c3_Err | 890 | return templ_7745c5c3_Err | ||
| 781 | } | 891 | } | ||
| 782 | } else { | 892 | } else { | ||
| 783 | - | var templ_7745c5c3_Var37 string | 893 | + | var templ_7745c5c3_Var45 string |
| 784 | - | templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) | 894 | + | templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(r.Short) |
| 785 | if templ_7745c5c3_Err != nil { | 895 | if templ_7745c5c3_Err != nil { | ||
| 786 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 172, Col: 13} | 896 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 180, Col: 13} |
| 787 | } | 897 | } | ||
| 788 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37)) | 898 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45)) |
| 789 | if templ_7745c5c3_Err != nil { | 899 | if templ_7745c5c3_Err != nil { | ||
| 790 | return templ_7745c5c3_Err | 900 | return templ_7745c5c3_Err | ||
| 791 | } | 901 | } | ||
| @@ -794,69 +904,69 @@ func refRow(kind string, r RefRow) templ.Component { | |||||
| 794 | if templ_7745c5c3_Err != nil { | 904 | if templ_7745c5c3_Err != nil { | ||
| 795 | return templ_7745c5c3_Err | 905 | return templ_7745c5c3_Err | ||
| 796 | } | 906 | } | ||
| 797 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "</td><td class=\"c-sub\">") | 907 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "</td><td class=\"c-sub\">") |
| 798 | if templ_7745c5c3_Err != nil { | 908 | if templ_7745c5c3_Err != nil { | ||
| 799 | return templ_7745c5c3_Err | 909 | return templ_7745c5c3_Err | ||
| 800 | } | 910 | } | ||
| 801 | - | var templ_7745c5c3_Var38 string | 911 | + | var templ_7745c5c3_Var46 string |
| 802 | - | templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject) | 912 | + | templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(r.Subject) |
| 803 | if templ_7745c5c3_Err != nil { | 913 | if templ_7745c5c3_Err != nil { | ||
| 804 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 176, Col: 31} | 914 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 184, Col: 31} |
| 805 | } | 915 | } | ||
| 806 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) | 916 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46)) |
| 807 | if templ_7745c5c3_Err != nil { | 917 | if templ_7745c5c3_Err != nil { | ||
| 808 | return templ_7745c5c3_Err | 918 | return templ_7745c5c3_Err | ||
| 809 | } | 919 | } | ||
| 810 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "</td><td class=\"c-when dim\">") | 920 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</td><td class=\"c-when dim\">") |
| 811 | if templ_7745c5c3_Err != nil { | 921 | if templ_7745c5c3_Err != nil { | ||
| 812 | return templ_7745c5c3_Err | 922 | return templ_7745c5c3_Err | ||
| 813 | } | 923 | } | ||
| 814 | if r.WhenAt != "" { | 924 | if r.WhenAt != "" { | ||
| 815 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "<time datetime=\"") | 925 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "<time datetime=\"") |
| 816 | if templ_7745c5c3_Err != nil { | 926 | if templ_7745c5c3_Err != nil { | ||
| 817 | return templ_7745c5c3_Err | 927 | return templ_7745c5c3_Err | ||
| 818 | } | 928 | } | ||
| 819 | - | var templ_7745c5c3_Var39 string | 929 | + | var templ_7745c5c3_Var47 string |
| 820 | - | templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | 930 | + | templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) |
| 821 | if templ_7745c5c3_Err != nil { | 931 | if templ_7745c5c3_Err != nil { | ||
| 822 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 29} | 932 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 29} |
| 823 | } | 933 | } | ||
| 824 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var39) | 934 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var47) |
| 825 | if templ_7745c5c3_Err != nil { | 935 | if templ_7745c5c3_Err != nil { | ||
| 826 | return templ_7745c5c3_Err | 936 | return templ_7745c5c3_Err | ||
| 827 | } | 937 | } | ||
| 828 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "\" title=\"") | 938 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "\" title=\"") |
| 829 | if templ_7745c5c3_Err != nil { | 939 | if templ_7745c5c3_Err != nil { | ||
| 830 | return templ_7745c5c3_Err | 940 | return templ_7745c5c3_Err | ||
| 831 | } | 941 | } | ||
| 832 | - | var templ_7745c5c3_Var40 string | 942 | + | var templ_7745c5c3_Var48 string |
| 833 | - | templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) | 943 | + | templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.WhenAt) |
| 834 | if templ_7745c5c3_Err != nil { | 944 | if templ_7745c5c3_Err != nil { | ||
| 835 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 48} | 945 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 48} |
| 836 | } | 946 | } | ||
| 837 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40) | 947 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var48) |
| 838 | if templ_7745c5c3_Err != nil { | 948 | if templ_7745c5c3_Err != nil { | ||
| 839 | return templ_7745c5c3_Err | 949 | return templ_7745c5c3_Err | ||
| 840 | } | 950 | } | ||
| 841 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "\">") | 951 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "\">") |
| 842 | if templ_7745c5c3_Err != nil { | 952 | if templ_7745c5c3_Err != nil { | ||
| 843 | return templ_7745c5c3_Err | 953 | return templ_7745c5c3_Err | ||
| 844 | } | 954 | } | ||
| 845 | - | var templ_7745c5c3_Var41 string | 955 | + | var templ_7745c5c3_Var49 string |
| 846 | - | templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(r.When) | 956 | + | templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(r.When) |
| 847 | if templ_7745c5c3_Err != nil { | 957 | if templ_7745c5c3_Err != nil { | ||
| 848 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 179, Col: 59} | 958 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 187, Col: 59} |
| 849 | } | 959 | } | ||
| 850 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41)) | 960 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49)) |
| 851 | if templ_7745c5c3_Err != nil { | 961 | if templ_7745c5c3_Err != nil { | ||
| 852 | return templ_7745c5c3_Err | 962 | return templ_7745c5c3_Err | ||
| 853 | } | 963 | } | ||
| 854 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "</time>") | 964 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</time>") |
| 855 | if templ_7745c5c3_Err != nil { | 965 | if templ_7745c5c3_Err != nil { | ||
| 856 | return templ_7745c5c3_Err | 966 | return templ_7745c5c3_Err | ||
| 857 | } | 967 | } | ||
| 858 | } | 968 | } | ||
| 859 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "</td></tr>") | 969 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</td></tr>") |
| 860 | if templ_7745c5c3_Err != nil { | 970 | if templ_7745c5c3_Err != nil { | ||
| 861 | return templ_7745c5c3_Err | 971 | return templ_7745c5c3_Err | ||
| 862 | } | 972 | } | ||
| @@ -880,12 +990,12 @@ func refsRail(p RefsPage) templ.Component { | |||||
| 880 | }() | 990 | }() | ||
| 881 | } | 991 | } | ||
| 882 | ctx = templ.InitializeContext(ctx) | 992 | ctx = templ.InitializeContext(ctx) | ||
| 883 | - | templ_7745c5c3_Var42 := templ.GetChildren(ctx) | 993 | + | templ_7745c5c3_Var50 := templ.GetChildren(ctx) |
| 884 | - | if templ_7745c5c3_Var42 == nil { | 994 | + | if templ_7745c5c3_Var50 == nil { |
| 885 | - | templ_7745c5c3_Var42 = templ.NopComponent | 995 | + | templ_7745c5c3_Var50 = templ.NopComponent |
| 886 | } | 996 | } | ||
| 887 | ctx = templ.ClearChildren(ctx) | 997 | ctx = templ.ClearChildren(ctx) | ||
| 888 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>") | 998 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "<section aria-labelledby=\"r-refs\"><h2 id=\"r-refs\">Overview</h2>") |
| 889 | if templ_7745c5c3_Err != nil { | 999 | if templ_7745c5c3_Err != nil { | ||
| 890 | return templ_7745c5c3_Err | 1000 | return templ_7745c5c3_Err | ||
| 891 | } | 1001 | } | ||
| @@ -893,7 +1003,7 @@ func refsRail(p RefsPage) templ.Component { | |||||
| 893 | if templ_7745c5c3_Err != nil { | 1003 | if templ_7745c5c3_Err != nil { | ||
| 894 | return templ_7745c5c3_Err | 1004 | return templ_7745c5c3_Err | ||
| 895 | } | 1005 | } | ||
| 896 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "</section>") | 1006 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</section>") |
| 897 | if templ_7745c5c3_Err != nil { | 1007 | if templ_7745c5c3_Err != nil { | ||
| 898 | return templ_7745c5c3_Err | 1008 | return templ_7745c5c3_Err | ||
| 899 | } | 1009 | } | ||
| @@ -918,12 +1028,12 @@ func State(l Layout, p StatePage) templ.Component { | |||||
| 918 | }() | 1028 | }() | ||
| 919 | } | 1029 | } | ||
| 920 | ctx = templ.InitializeContext(ctx) | 1030 | ctx = templ.InitializeContext(ctx) | ||
| 921 | - | templ_7745c5c3_Var43 := templ.GetChildren(ctx) | 1031 | + | templ_7745c5c3_Var51 := templ.GetChildren(ctx) |
| 922 | - | if templ_7745c5c3_Var43 == nil { | 1032 | + | if templ_7745c5c3_Var51 == nil { |
| 923 | - | templ_7745c5c3_Var43 = templ.NopComponent | 1033 | + | templ_7745c5c3_Var51 = templ.NopComponent |
| 924 | } | 1034 | } | ||
| 925 | ctx = templ.ClearChildren(ctx) | 1035 | ctx = templ.ClearChildren(ctx) | ||
| 926 | - | templ_7745c5c3_Var44 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 1036 | + | templ_7745c5c3_Var52 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { |
| 927 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | 1037 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||
| 928 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | 1038 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||
| 929 | if !templ_7745c5c3_IsBuffer { | 1039 | if !templ_7745c5c3_IsBuffer { | ||
| @@ -935,51 +1045,51 @@ func State(l Layout, p StatePage) templ.Component { | |||||
| 935 | }() | 1045 | }() | ||
| 936 | } | 1046 | } | ||
| 937 | ctx = templ.InitializeContext(ctx) | 1047 | ctx = templ.InitializeContext(ctx) | ||
| 938 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">") | 1048 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "<section class=\"state\" aria-labelledby=\"state-title\"><p class=\"eyebrow\">") |
| 939 | if templ_7745c5c3_Err != nil { | 1049 | if templ_7745c5c3_Err != nil { | ||
| 940 | return templ_7745c5c3_Err | 1050 | return templ_7745c5c3_Err | ||
| 941 | } | 1051 | } | ||
| 942 | - | var templ_7745c5c3_Var45 string | 1052 | + | var templ_7745c5c3_Var53 string |
| 943 | - | templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code) | 1053 | + | templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(p.Code) |
| 944 | if templ_7745c5c3_Err != nil { | 1054 | if templ_7745c5c3_Err != nil { | ||
| 945 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 196, Col: 30} | 1055 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 204, Col: 30} |
| 946 | } | 1056 | } | ||
| 947 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45)) | 1057 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53)) |
| 948 | if templ_7745c5c3_Err != nil { | 1058 | if templ_7745c5c3_Err != nil { | ||
| 949 | return templ_7745c5c3_Err | 1059 | return templ_7745c5c3_Err | ||
| 950 | } | 1060 | } | ||
| 951 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "</p><h1 id=\"state-title\">") | 1061 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "</p><h1 id=\"state-title\">") |
| 952 | if templ_7745c5c3_Err != nil { | 1062 | if templ_7745c5c3_Err != nil { | ||
| 953 | return templ_7745c5c3_Err | 1063 | return templ_7745c5c3_Err | ||
| 954 | } | 1064 | } | ||
| 955 | - | var templ_7745c5c3_Var46 string | 1065 | + | var templ_7745c5c3_Var54 string |
| 956 | - | templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | 1066 | + | templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) |
| 957 | if templ_7745c5c3_Err != nil { | 1067 | if templ_7745c5c3_Err != nil { | ||
| 958 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 197, Col: 33} | 1068 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 205, Col: 33} |
| 959 | } | 1069 | } | ||
| 960 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46)) | 1070 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54)) |
| 961 | if templ_7745c5c3_Err != nil { | 1071 | if templ_7745c5c3_Err != nil { | ||
| 962 | return templ_7745c5c3_Err | 1072 | return templ_7745c5c3_Err | ||
| 963 | } | 1073 | } | ||
| 964 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "</h1>") | 1074 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>") |
| 965 | if templ_7745c5c3_Err != nil { | 1075 | if templ_7745c5c3_Err != nil { | ||
| 966 | return templ_7745c5c3_Err | 1076 | return templ_7745c5c3_Err | ||
| 967 | } | 1077 | } | ||
| 968 | for _, line := range p.Lines { | 1078 | for _, line := range p.Lines { | ||
| 969 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "<p class=\"dim\">") | 1079 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">") |
| 970 | if templ_7745c5c3_Err != nil { | 1080 | if templ_7745c5c3_Err != nil { | ||
| 971 | return templ_7745c5c3_Err | 1081 | return templ_7745c5c3_Err | ||
| 972 | } | 1082 | } | ||
| 973 | - | var templ_7745c5c3_Var47 string | 1083 | + | var templ_7745c5c3_Var55 string |
| 974 | - | templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(line) | 1084 | + | templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(line) |
| 975 | if templ_7745c5c3_Err != nil { | 1085 | if templ_7745c5c3_Err != nil { | ||
| 976 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 199, Col: 25} | 1086 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 207, Col: 25} |
| 977 | } | 1087 | } | ||
| 978 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47)) | 1088 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55)) |
| 979 | if templ_7745c5c3_Err != nil { | 1089 | if templ_7745c5c3_Err != nil { | ||
| 980 | return templ_7745c5c3_Err | 1090 | return templ_7745c5c3_Err | ||
| 981 | } | 1091 | } | ||
| 982 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</p>") | 1092 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>") |
| 983 | if templ_7745c5c3_Err != nil { | 1093 | if templ_7745c5c3_Err != nil { | ||
| 984 | return templ_7745c5c3_Err | 1094 | return templ_7745c5c3_Err | ||
| 985 | } | 1095 | } | ||
| @@ -990,49 +1100,49 @@ func State(l Layout, p StatePage) templ.Component { | |||||
| 990 | return templ_7745c5c3_Err | 1100 | return templ_7745c5c3_Err | ||
| 991 | } | 1101 | } | ||
| 992 | } | 1102 | } | ||
| 993 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "<p class=\"state-back\">") | 1103 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<p class=\"state-back\">") |
| 994 | if templ_7745c5c3_Err != nil { | 1104 | if templ_7745c5c3_Err != nil { | ||
| 995 | return templ_7745c5c3_Err | 1105 | return templ_7745c5c3_Err | ||
| 996 | } | 1106 | } | ||
| 997 | for _, b := range p.Back { | 1107 | for _, b := range p.Back { | ||
| 998 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "<a href=\"") | 1108 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "<a href=\"") |
| 999 | if templ_7745c5c3_Err != nil { | 1109 | if templ_7745c5c3_Err != nil { | ||
| 1000 | return templ_7745c5c3_Err | 1110 | return templ_7745c5c3_Err | ||
| 1001 | } | 1111 | } | ||
| 1002 | - | var templ_7745c5c3_Var48 templ.SafeURL | 1112 | + | var templ_7745c5c3_Var56 templ.SafeURL |
| 1003 | - | templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href)) | 1113 | + | templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(b.Href)) |
| 1004 | if templ_7745c5c3_Err != nil { | 1114 | if templ_7745c5c3_Err != nil { | ||
| 1005 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 36} | 1115 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 36} |
| 1006 | } | 1116 | } | ||
| 1007 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48)) | 1117 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56)) |
| 1008 | if templ_7745c5c3_Err != nil { | 1118 | if templ_7745c5c3_Err != nil { | ||
| 1009 | return templ_7745c5c3_Err | 1119 | return templ_7745c5c3_Err | ||
| 1010 | } | 1120 | } | ||
| 1011 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "\">") | 1121 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "\">") |
| 1012 | if templ_7745c5c3_Err != nil { | 1122 | if templ_7745c5c3_Err != nil { | ||
| 1013 | return templ_7745c5c3_Err | 1123 | return templ_7745c5c3_Err | ||
| 1014 | } | 1124 | } | ||
| 1015 | - | var templ_7745c5c3_Var49 string | 1125 | + | var templ_7745c5c3_Var57 string |
| 1016 | - | templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label) | 1126 | + | templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(b.Label) |
| 1017 | if templ_7745c5c3_Err != nil { | 1127 | if templ_7745c5c3_Err != nil { | ||
| 1018 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 206, Col: 48} | 1128 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 214, Col: 48} |
| 1019 | } | 1129 | } | ||
| 1020 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49)) | 1130 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57)) |
| 1021 | if templ_7745c5c3_Err != nil { | 1131 | if templ_7745c5c3_Err != nil { | ||
| 1022 | return templ_7745c5c3_Err | 1132 | return templ_7745c5c3_Err | ||
| 1023 | } | 1133 | } | ||
| 1024 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "</a>") | 1134 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "</a>") |
| 1025 | if templ_7745c5c3_Err != nil { | 1135 | if templ_7745c5c3_Err != nil { | ||
| 1026 | return templ_7745c5c3_Err | 1136 | return templ_7745c5c3_Err | ||
| 1027 | } | 1137 | } | ||
| 1028 | } | 1138 | } | ||
| 1029 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "</p></section>") | 1139 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</p></section>") |
| 1030 | if templ_7745c5c3_Err != nil { | 1140 | if templ_7745c5c3_Err != nil { | ||
| 1031 | return templ_7745c5c3_Err | 1141 | return templ_7745c5c3_Err | ||
| 1032 | } | 1142 | } | ||
| 1033 | return nil | 1143 | return nil | ||
| 1034 | }) | 1144 | }) | ||
| 1035 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var44), templ_7745c5c3_Buffer) | 1145 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var52), templ_7745c5c3_Buffer) |
| 1036 | if templ_7745c5c3_Err != nil { | 1146 | if templ_7745c5c3_Err != nil { | ||
| 1037 | return templ_7745c5c3_Err | 1147 | return templ_7745c5c3_Err | ||
| 1038 | } | 1148 | } | ||
| @@ -1061,12 +1171,12 @@ func Login(l Layout, p LoginPage) templ.Component { | |||||
| 1061 | }() | 1171 | }() | ||
| 1062 | } | 1172 | } | ||
| 1063 | ctx = templ.InitializeContext(ctx) | 1173 | ctx = templ.InitializeContext(ctx) | ||
| 1064 | - | templ_7745c5c3_Var50 := templ.GetChildren(ctx) | 1174 | + | templ_7745c5c3_Var58 := templ.GetChildren(ctx) |
| 1065 | - | if templ_7745c5c3_Var50 == nil { | 1175 | + | if templ_7745c5c3_Var58 == nil { |
| 1066 | - | templ_7745c5c3_Var50 = templ.NopComponent | 1176 | + | templ_7745c5c3_Var58 = templ.NopComponent |
| 1067 | } | 1177 | } | ||
| 1068 | ctx = templ.ClearChildren(ctx) | 1178 | ctx = templ.ClearChildren(ctx) | ||
| 1069 | - | templ_7745c5c3_Var51 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 1179 | + | templ_7745c5c3_Var59 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { |
| 1070 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | 1180 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||
| 1071 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | 1181 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||
| 1072 | if !templ_7745c5c3_IsBuffer { | 1182 | if !templ_7745c5c3_IsBuffer { | ||
| @@ -1078,75 +1188,75 @@ func Login(l Layout, p LoginPage) templ.Component { | |||||
| 1078 | }() | 1188 | }() | ||
| 1079 | } | 1189 | } | ||
| 1080 | ctx = templ.InitializeContext(ctx) | 1190 | ctx = templ.InitializeContext(ctx) | ||
| 1081 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") | 1191 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") |
| 1082 | if templ_7745c5c3_Err != nil { | 1192 | if templ_7745c5c3_Err != nil { | ||
| 1083 | return templ_7745c5c3_Err | 1193 | return templ_7745c5c3_Err | ||
| 1084 | } | 1194 | } | ||
| 1085 | - | var templ_7745c5c3_Var52 string | 1195 | + | var templ_7745c5c3_Var60 string |
| 1086 | - | templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | 1196 | + | templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) |
| 1087 | if templ_7745c5c3_Err != nil { | 1197 | if templ_7745c5c3_Err != nil { | ||
| 1088 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 221, Col: 33} | 1198 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 229, Col: 33} |
| 1089 | } | 1199 | } | ||
| 1090 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52)) | 1200 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60)) |
| 1091 | if templ_7745c5c3_Err != nil { | 1201 | if templ_7745c5c3_Err != nil { | ||
| 1092 | return templ_7745c5c3_Err | 1202 | return templ_7745c5c3_Err | ||
| 1093 | } | 1203 | } | ||
| 1094 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "</h1>") | 1204 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "</h1>") |
| 1095 | if templ_7745c5c3_Err != nil { | 1205 | if templ_7745c5c3_Err != nil { | ||
| 1096 | return templ_7745c5c3_Err | 1206 | return templ_7745c5c3_Err | ||
| 1097 | } | 1207 | } | ||
| 1098 | for _, line := range p.Lines { | 1208 | for _, line := range p.Lines { | ||
| 1099 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "<p class=\"dim\">") | 1209 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "<p class=\"dim\">") |
| 1100 | if templ_7745c5c3_Err != nil { | 1210 | if templ_7745c5c3_Err != nil { | ||
| 1101 | return templ_7745c5c3_Err | 1211 | return templ_7745c5c3_Err | ||
| 1102 | } | 1212 | } | ||
| 1103 | - | var templ_7745c5c3_Var53 string | 1213 | + | var templ_7745c5c3_Var61 string |
| 1104 | - | templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(line) | 1214 | + | templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(line) |
| 1105 | if templ_7745c5c3_Err != nil { | 1215 | if templ_7745c5c3_Err != nil { | ||
| 1106 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 223, Col: 25} | 1216 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 231, Col: 25} |
| 1107 | } | 1217 | } | ||
| 1108 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53)) | 1218 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61)) |
| 1109 | if templ_7745c5c3_Err != nil { | 1219 | if templ_7745c5c3_Err != nil { | ||
| 1110 | return templ_7745c5c3_Err | 1220 | return templ_7745c5c3_Err | ||
| 1111 | } | 1221 | } | ||
| 1112 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "</p>") | 1222 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "</p>") |
| 1113 | if templ_7745c5c3_Err != nil { | 1223 | if templ_7745c5c3_Err != nil { | ||
| 1114 | return templ_7745c5c3_Err | 1224 | return templ_7745c5c3_Err | ||
| 1115 | } | 1225 | } | ||
| 1116 | } | 1226 | } | ||
| 1117 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "<form class=\"state-act\" method=\"post\" action=\"") | 1227 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "<form class=\"state-act\" method=\"post\" action=\"") |
| 1118 | if templ_7745c5c3_Err != nil { | 1228 | if templ_7745c5c3_Err != nil { | ||
| 1119 | return templ_7745c5c3_Err | 1229 | return templ_7745c5c3_Err | ||
| 1120 | } | 1230 | } | ||
| 1121 | - | var templ_7745c5c3_Var54 templ.SafeURL | 1231 | + | var templ_7745c5c3_Var62 templ.SafeURL |
| 1122 | - | templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action)) | 1232 | + | templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Action)) |
| 1123 | if templ_7745c5c3_Err != nil { | 1233 | if templ_7745c5c3_Err != nil { | ||
| 1124 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 225, Col: 73} | 1234 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 233, Col: 73} |
| 1125 | } | 1235 | } | ||
| 1126 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54)) | 1236 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) |
| 1127 | if templ_7745c5c3_Err != nil { | 1237 | if templ_7745c5c3_Err != nil { | ||
| 1128 | return templ_7745c5c3_Err | 1238 | return templ_7745c5c3_Err | ||
| 1129 | } | 1239 | } | ||
| 1130 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">") | 1240 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "\" data-autosubmit><button type=\"submit\" class=\"btn primary\">") |
| 1131 | if templ_7745c5c3_Err != nil { | 1241 | if templ_7745c5c3_Err != nil { | ||
| 1132 | return templ_7745c5c3_Err | 1242 | return templ_7745c5c3_Err | ||
| 1133 | } | 1243 | } | ||
| 1134 | - | var templ_7745c5c3_Var55 string | 1244 | + | var templ_7745c5c3_Var63 string |
| 1135 | - | templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) | 1245 | + | templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) |
| 1136 | if templ_7745c5c3_Err != nil { | 1246 | if templ_7745c5c3_Err != nil { | ||
| 1137 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 226, Col: 56} | 1247 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 234, Col: 56} |
| 1138 | } | 1248 | } | ||
| 1139 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55)) | 1249 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63)) |
| 1140 | if templ_7745c5c3_Err != nil { | 1250 | if templ_7745c5c3_Err != nil { | ||
| 1141 | return templ_7745c5c3_Err | 1251 | return templ_7745c5c3_Err | ||
| 1142 | } | 1252 | } | ||
| 1143 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") | 1253 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "</button></form><p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") |
| 1144 | if templ_7745c5c3_Err != nil { | 1254 | if templ_7745c5c3_Err != nil { | ||
| 1145 | return templ_7745c5c3_Err | 1255 | return templ_7745c5c3_Err | ||
| 1146 | } | 1256 | } | ||
| 1147 | return nil | 1257 | return nil | ||
| 1148 | }) | 1258 | }) | ||
| 1149 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var51), templ_7745c5c3_Buffer) | 1259 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var59), templ_7745c5c3_Buffer) |
| 1150 | if templ_7745c5c3_Err != nil { | 1260 | if templ_7745c5c3_Err != nil { | ||
| 1151 | return templ_7745c5c3_Err | 1261 | return templ_7745c5c3_Err | ||
| 1152 | } | 1262 | } | ||
| @@ -1172,12 +1282,12 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component { | |||||
| 1172 | }() | 1282 | }() | ||
| 1173 | } | 1283 | } | ||
| 1174 | ctx = templ.InitializeContext(ctx) | 1284 | ctx = templ.InitializeContext(ctx) | ||
| 1175 | - | templ_7745c5c3_Var56 := templ.GetChildren(ctx) | 1285 | + | templ_7745c5c3_Var64 := templ.GetChildren(ctx) |
| 1176 | - | if templ_7745c5c3_Var56 == nil { | 1286 | + | if templ_7745c5c3_Var64 == nil { |
| 1177 | - | templ_7745c5c3_Var56 = templ.NopComponent | 1287 | + | templ_7745c5c3_Var64 = templ.NopComponent |
| 1178 | } | 1288 | } | ||
| 1179 | ctx = templ.ClearChildren(ctx) | 1289 | ctx = templ.ClearChildren(ctx) | ||
| 1180 | - | templ_7745c5c3_Var57 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 1290 | + | templ_7745c5c3_Var65 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { |
| 1181 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | 1291 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||
| 1182 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | 1292 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||
| 1183 | if !templ_7745c5c3_IsBuffer { | 1293 | if !templ_7745c5c3_IsBuffer { | ||
| @@ -1189,88 +1299,88 @@ func PasskeyLogin(l Layout, p PasskeyLoginPage) templ.Component { | |||||
| 1189 | }() | 1299 | }() | ||
| 1190 | } | 1300 | } | ||
| 1191 | ctx = templ.InitializeContext(ctx) | 1301 | ctx = templ.InitializeContext(ctx) | ||
| 1192 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") | 1302 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "<section class=\"state\" aria-labelledby=\"state-title\"><h1 id=\"state-title\">") |
| 1193 | if templ_7745c5c3_Err != nil { | 1303 | if templ_7745c5c3_Err != nil { | ||
| 1194 | return templ_7745c5c3_Err | 1304 | return templ_7745c5c3_Err | ||
| 1195 | } | 1305 | } | ||
| 1196 | - | var templ_7745c5c3_Var58 string | 1306 | + | var templ_7745c5c3_Var66 string |
| 1197 | - | templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) | 1307 | + | templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) |
| 1198 | if templ_7745c5c3_Err != nil { | 1308 | if templ_7745c5c3_Err != nil { | ||
| 1199 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 238, Col: 33} | 1309 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 246, Col: 33} |
| 1200 | } | 1310 | } | ||
| 1201 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58)) | 1311 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) |
| 1202 | if templ_7745c5c3_Err != nil { | 1312 | if templ_7745c5c3_Err != nil { | ||
| 1203 | return templ_7745c5c3_Err | 1313 | return templ_7745c5c3_Err | ||
| 1204 | } | 1314 | } | ||
| 1205 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"") | 1315 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "</h1><form class=\"state-act\" data-js data-passkey-form><button type=\"submit\" class=\"btn primary\" data-passkey=\"login\" data-begin=\"") |
| 1206 | if templ_7745c5c3_Err != nil { | 1316 | if templ_7745c5c3_Err != nil { | ||
| 1207 | return templ_7745c5c3_Err | 1317 | return templ_7745c5c3_Err | ||
| 1208 | } | 1318 | } | ||
| 1209 | - | var templ_7745c5c3_Var59 string | 1319 | + | var templ_7745c5c3_Var67 string |
| 1210 | - | templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) | 1320 | + | templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) |
| 1211 | if templ_7745c5c3_Err != nil { | 1321 | if templ_7745c5c3_Err != nil { | ||
| 1212 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 87} | 1322 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 87} |
| 1213 | } | 1323 | } | ||
| 1214 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var59) | 1324 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67) |
| 1215 | if templ_7745c5c3_Err != nil { | 1325 | if templ_7745c5c3_Err != nil { | ||
| 1216 | return templ_7745c5c3_Err | 1326 | return templ_7745c5c3_Err | ||
| 1217 | } | 1327 | } | ||
| 1218 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "\" data-finish=\"") | 1328 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "\" data-finish=\"") |
| 1219 | if templ_7745c5c3_Err != nil { | 1329 | if templ_7745c5c3_Err != nil { | ||
| 1220 | return templ_7745c5c3_Err | 1330 | return templ_7745c5c3_Err | ||
| 1221 | } | 1331 | } | ||
| 1222 | - | var templ_7745c5c3_Var60 string | 1332 | + | var templ_7745c5c3_Var68 string |
| 1223 | - | templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) | 1333 | + | templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) |
| 1224 | if templ_7745c5c3_Err != nil { | 1334 | if templ_7745c5c3_Err != nil { | ||
| 1225 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 112} | 1335 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 112} |
| 1226 | } | 1336 | } | ||
| 1227 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var60) | 1337 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var68) |
| 1228 | if templ_7745c5c3_Err != nil { | 1338 | if templ_7745c5c3_Err != nil { | ||
| 1229 | return templ_7745c5c3_Err | 1339 | return templ_7745c5c3_Err | ||
| 1230 | } | 1340 | } | ||
| 1231 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "\">") | 1341 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "\">") |
| 1232 | if templ_7745c5c3_Err != nil { | 1342 | if templ_7745c5c3_Err != nil { | ||
| 1233 | return templ_7745c5c3_Err | 1343 | return templ_7745c5c3_Err | ||
| 1234 | } | 1344 | } | ||
| 1235 | - | var templ_7745c5c3_Var61 string | 1345 | + | var templ_7745c5c3_Var69 string |
| 1236 | - | templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) | 1346 | + | templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.JoinStringErrs(p.Button) |
| 1237 | if templ_7745c5c3_Err != nil { | 1347 | if templ_7745c5c3_Err != nil { | ||
| 1238 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 240, Col: 125} | 1348 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 248, Col: 125} |
| 1239 | } | 1349 | } | ||
| 1240 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61)) | 1350 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var69)) |
| 1241 | if templ_7745c5c3_Err != nil { | 1351 | if templ_7745c5c3_Err != nil { | ||
| 1242 | return templ_7745c5c3_Err | 1352 | return templ_7745c5c3_Err | ||
| 1243 | } | 1353 | } | ||
| 1244 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") | 1354 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "</button></form><p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") |
| 1245 | if templ_7745c5c3_Err != nil { | 1355 | if templ_7745c5c3_Err != nil { | ||
| 1246 | return templ_7745c5c3_Err | 1356 | return templ_7745c5c3_Err | ||
| 1247 | } | 1357 | } | ||
| 1248 | for _, line := range p.Lines { | 1358 | for _, line := range p.Lines { | ||
| 1249 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "<p class=\"dim\">") | 1359 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "<p class=\"dim\">") |
| 1250 | if templ_7745c5c3_Err != nil { | 1360 | if templ_7745c5c3_Err != nil { | ||
| 1251 | return templ_7745c5c3_Err | 1361 | return templ_7745c5c3_Err | ||
| 1252 | } | 1362 | } | ||
| 1253 | - | var templ_7745c5c3_Var62 string | 1363 | + | var templ_7745c5c3_Var70 string |
| 1254 | - | templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(line) | 1364 | + | templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(line) |
| 1255 | if templ_7745c5c3_Err != nil { | 1365 | if templ_7745c5c3_Err != nil { | ||
| 1256 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 244, Col: 25} | 1366 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 252, Col: 25} |
| 1257 | } | 1367 | } | ||
| 1258 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) | 1368 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70)) |
| 1259 | if templ_7745c5c3_Err != nil { | 1369 | if templ_7745c5c3_Err != nil { | ||
| 1260 | return templ_7745c5c3_Err | 1370 | return templ_7745c5c3_Err | ||
| 1261 | } | 1371 | } | ||
| 1262 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "</p>") | 1372 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "</p>") |
| 1263 | if templ_7745c5c3_Err != nil { | 1373 | if templ_7745c5c3_Err != nil { | ||
| 1264 | return templ_7745c5c3_Err | 1374 | return templ_7745c5c3_Err | ||
| 1265 | } | 1375 | } | ||
| 1266 | } | 1376 | } | ||
| 1267 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") | 1377 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "<p class=\"state-back\"><a href=\"/\">Back to home</a></p></section>") |
| 1268 | if templ_7745c5c3_Err != nil { | 1378 | if templ_7745c5c3_Err != nil { | ||
| 1269 | return templ_7745c5c3_Err | 1379 | return templ_7745c5c3_Err | ||
| 1270 | } | 1380 | } | ||
| 1271 | return nil | 1381 | return nil | ||
| 1272 | }) | 1382 | }) | ||
| 1273 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var57), templ_7745c5c3_Buffer) | 1383 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var65), templ_7745c5c3_Buffer) |
| 1274 | if templ_7745c5c3_Err != nil { | 1384 | if templ_7745c5c3_Err != nil { | ||
| 1275 | return templ_7745c5c3_Err | 1385 | return templ_7745c5c3_Err | ||
| 1276 | } | 1386 | } | ||
| @@ -1295,12 +1405,12 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component { | |||||
| 1295 | }() | 1405 | }() | ||
| 1296 | } | 1406 | } | ||
| 1297 | ctx = templ.InitializeContext(ctx) | 1407 | ctx = templ.InitializeContext(ctx) | ||
| 1298 | - | templ_7745c5c3_Var63 := templ.GetChildren(ctx) | 1408 | + | templ_7745c5c3_Var71 := templ.GetChildren(ctx) |
| 1299 | - | if templ_7745c5c3_Var63 == nil { | 1409 | + | if templ_7745c5c3_Var71 == nil { |
| 1300 | - | templ_7745c5c3_Var63 = templ.NopComponent | 1410 | + | templ_7745c5c3_Var71 = templ.NopComponent |
| 1301 | } | 1411 | } | ||
| 1302 | ctx = templ.ClearChildren(ctx) | 1412 | ctx = templ.ClearChildren(ctx) | ||
| 1303 | - | templ_7745c5c3_Var64 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { | 1413 | + | templ_7745c5c3_Var72 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { |
| 1304 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | 1414 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context | ||
| 1305 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | 1415 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) | ||
| 1306 | if !templ_7745c5c3_IsBuffer { | 1416 | if !templ_7745c5c3_IsBuffer { | ||
| @@ -1312,231 +1422,231 @@ func Passkeys(l Layout, p PasskeysPage) templ.Component { | |||||
| 1312 | }() | 1422 | }() | ||
| 1313 | } | 1423 | } | ||
| 1314 | ctx = templ.InitializeContext(ctx) | 1424 | ctx = templ.InitializeContext(ctx) | ||
| 1315 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">") | 1425 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "<h2 class=\"rule-h\"><span>Passkeys</span><span class=\"count\">") |
| 1316 | if templ_7745c5c3_Err != nil { | 1426 | if templ_7745c5c3_Err != nil { | ||
| 1317 | return templ_7745c5c3_Err | 1427 | return templ_7745c5c3_Err | ||
| 1318 | } | 1428 | } | ||
| 1319 | - | var templ_7745c5c3_Var65 string | 1429 | + | var templ_7745c5c3_Var73 string |
| 1320 | - | templ_7745c5c3_Var65, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows))) | 1430 | + | templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(len(p.Rows))) |
| 1321 | if templ_7745c5c3_Err != nil { | 1431 | if templ_7745c5c3_Err != nil { | ||
| 1322 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 254, Col: 81} | 1432 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 262, Col: 81} |
| 1323 | } | 1433 | } | ||
| 1324 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var65)) | 1434 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73)) |
| 1325 | if templ_7745c5c3_Err != nil { | 1435 | if templ_7745c5c3_Err != nil { | ||
| 1326 | return templ_7745c5c3_Err | 1436 | return templ_7745c5c3_Err | ||
| 1327 | } | 1437 | } | ||
| 1328 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>") | 1438 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "</span></h2><p class=\"dim\">A passkey signs you in from this device or your phone, without a terminal. Removing one signs every browser out.</p>") |
| 1329 | if templ_7745c5c3_Err != nil { | 1439 | if templ_7745c5c3_Err != nil { | ||
| 1330 | return templ_7745c5c3_Err | 1440 | return templ_7745c5c3_Err | ||
| 1331 | } | 1441 | } | ||
| 1332 | if len(p.Rows) > 0 { | 1442 | if len(p.Rows) > 0 { | ||
| 1333 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>") | 1443 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "<table class=\"list passkeys\" aria-label=\"Passkeys\"><thead><tr><th class=\"c-name\">Name</th><th class=\"c-when\">Created</th><th class=\"c-when\">Last used</th><th class=\"c-sync\">Synced</th><th class=\"c-act\"><span class=\"sr\">Remove</span></th></tr></thead> <tbody>") |
| 1334 | if templ_7745c5c3_Err != nil { | 1444 | if templ_7745c5c3_Err != nil { | ||
| 1335 | return templ_7745c5c3_Err | 1445 | return templ_7745c5c3_Err | ||
| 1336 | } | 1446 | } | ||
| 1337 | for _, r := range p.Rows { | 1447 | for _, r := range p.Rows { | ||
| 1338 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "<tr><td class=\"c-name\">") | 1448 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "<tr><td class=\"c-name\">") |
| 1339 | if templ_7745c5c3_Err != nil { | 1449 | if templ_7745c5c3_Err != nil { | ||
| 1340 | return templ_7745c5c3_Err | 1450 | return templ_7745c5c3_Err | ||
| 1341 | } | 1451 | } | ||
| 1342 | - | var templ_7745c5c3_Var66 string | 1452 | + | var templ_7745c5c3_Var74 string |
| 1343 | - | templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) | 1453 | + | templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) |
| 1344 | if templ_7745c5c3_Err != nil { | 1454 | if templ_7745c5c3_Err != nil { | ||
| 1345 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 270, Col: 34} | 1455 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 278, Col: 34} |
| 1346 | } | 1456 | } | ||
| 1347 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) | 1457 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var74)) |
| 1348 | if templ_7745c5c3_Err != nil { | 1458 | if templ_7745c5c3_Err != nil { | ||
| 1349 | return templ_7745c5c3_Err | 1459 | return templ_7745c5c3_Err | ||
| 1350 | } | 1460 | } | ||
| 1351 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "</td><td class=\"c-when nowrap\"><time") | 1461 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "</td><td class=\"c-when nowrap\"><time") |
| 1352 | if templ_7745c5c3_Err != nil { | 1462 | if templ_7745c5c3_Err != nil { | ||
| 1353 | return templ_7745c5c3_Err | 1463 | return templ_7745c5c3_Err | ||
| 1354 | } | 1464 | } | ||
| 1355 | if r.CreatedAt != "" { | 1465 | if r.CreatedAt != "" { | ||
| 1356 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, " datetime=\"") | 1466 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, " datetime=\"") |
| 1357 | if templ_7745c5c3_Err != nil { | 1467 | if templ_7745c5c3_Err != nil { | ||
| 1358 | return templ_7745c5c3_Err | 1468 | return templ_7745c5c3_Err | ||
| 1359 | } | 1469 | } | ||
| 1360 | - | var templ_7745c5c3_Var67 string | 1470 | + | var templ_7745c5c3_Var75 string |
| 1361 | - | templ_7745c5c3_Var67, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt) | 1471 | + | templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.CreatedAt) |
| 1362 | if templ_7745c5c3_Err != nil { | 1472 | if templ_7745c5c3_Err != nil { | ||
| 1363 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 274, Col: 32} | 1473 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 282, Col: 32} |
| 1364 | } | 1474 | } | ||
| 1365 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var67) | 1475 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75) |
| 1366 | if templ_7745c5c3_Err != nil { | 1476 | if templ_7745c5c3_Err != nil { | ||
| 1367 | return templ_7745c5c3_Err | 1477 | return templ_7745c5c3_Err | ||
| 1368 | } | 1478 | } | ||
| 1369 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "\"") | 1479 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "\"") |
| 1370 | if templ_7745c5c3_Err != nil { | 1480 | if templ_7745c5c3_Err != nil { | ||
| 1371 | return templ_7745c5c3_Err | 1481 | return templ_7745c5c3_Err | ||
| 1372 | } | 1482 | } | ||
| 1373 | } | 1483 | } | ||
| 1374 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, ">") | 1484 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, ">") |
| 1375 | if templ_7745c5c3_Err != nil { | 1485 | if templ_7745c5c3_Err != nil { | ||
| 1376 | return templ_7745c5c3_Err | 1486 | return templ_7745c5c3_Err | ||
| 1377 | } | 1487 | } | ||
| 1378 | - | var templ_7745c5c3_Var68 string | 1488 | + | var templ_7745c5c3_Var76 string |
| 1379 | - | templ_7745c5c3_Var68, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created) | 1489 | + | templ_7745c5c3_Var76, templ_7745c5c3_Err = templ.JoinStringErrs(r.Created) |
| 1380 | if templ_7745c5c3_Err != nil { | 1490 | if templ_7745c5c3_Err != nil { | ||
| 1381 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 276, Col: 20} | 1491 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 284, Col: 20} |
| 1382 | } | 1492 | } | ||
| 1383 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var68)) | 1493 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var76)) |
| 1384 | if templ_7745c5c3_Err != nil { | 1494 | if templ_7745c5c3_Err != nil { | ||
| 1385 | return templ_7745c5c3_Err | 1495 | return templ_7745c5c3_Err | ||
| 1386 | } | 1496 | } | ||
| 1387 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "</time></td><td class=\"c-when nowrap\"><time") | 1497 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "</time></td><td class=\"c-when nowrap\"><time") |
| 1388 | if templ_7745c5c3_Err != nil { | 1498 | if templ_7745c5c3_Err != nil { | ||
| 1389 | return templ_7745c5c3_Err | 1499 | return templ_7745c5c3_Err | ||
| 1390 | } | 1500 | } | ||
| 1391 | if r.LastUsedAt != "" { | 1501 | if r.LastUsedAt != "" { | ||
| 1392 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " datetime=\"") | 1502 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, " datetime=\"") |
| 1393 | if templ_7745c5c3_Err != nil { | 1503 | if templ_7745c5c3_Err != nil { | ||
| 1394 | return templ_7745c5c3_Err | 1504 | return templ_7745c5c3_Err | ||
| 1395 | } | 1505 | } | ||
| 1396 | - | var templ_7745c5c3_Var69 string | 1506 | + | var templ_7745c5c3_Var77 string |
| 1397 | - | templ_7745c5c3_Var69, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt) | 1507 | + | templ_7745c5c3_Var77, templ_7745c5c3_Err = templ.ResolveAttributeValue(r.LastUsedAt) |
| 1398 | if templ_7745c5c3_Err != nil { | 1508 | if templ_7745c5c3_Err != nil { | ||
| 1399 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 281, Col: 33} | 1509 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 289, Col: 33} |
| 1400 | } | 1510 | } | ||
| 1401 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var69) | 1511 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var77) |
| 1402 | if templ_7745c5c3_Err != nil { | 1512 | if templ_7745c5c3_Err != nil { | ||
| 1403 | return templ_7745c5c3_Err | 1513 | return templ_7745c5c3_Err | ||
| 1404 | } | 1514 | } | ||
| 1405 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "\"") | 1515 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "\"") |
| 1406 | if templ_7745c5c3_Err != nil { | 1516 | if templ_7745c5c3_Err != nil { | ||
| 1407 | return templ_7745c5c3_Err | 1517 | return templ_7745c5c3_Err | ||
| 1408 | } | 1518 | } | ||
| 1409 | } | 1519 | } | ||
| 1410 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, ">") | 1520 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, ">") |
| 1411 | if templ_7745c5c3_Err != nil { | 1521 | if templ_7745c5c3_Err != nil { | ||
| 1412 | return templ_7745c5c3_Err | 1522 | return templ_7745c5c3_Err | ||
| 1413 | } | 1523 | } | ||
| 1414 | - | var templ_7745c5c3_Var70 string | 1524 | + | var templ_7745c5c3_Var78 string |
| 1415 | - | templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed) | 1525 | + | templ_7745c5c3_Var78, templ_7745c5c3_Err = templ.JoinStringErrs(r.LastUsed) |
| 1416 | if templ_7745c5c3_Err != nil { | 1526 | if templ_7745c5c3_Err != nil { | ||
| 1417 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 283, Col: 21} | 1527 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 291, Col: 21} |
| 1418 | } | 1528 | } | ||
| 1419 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70)) | 1529 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var78)) |
| 1420 | if templ_7745c5c3_Err != nil { | 1530 | if templ_7745c5c3_Err != nil { | ||
| 1421 | return templ_7745c5c3_Err | 1531 | return templ_7745c5c3_Err | ||
| 1422 | } | 1532 | } | ||
| 1423 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "</time></td><td class=\"c-sync\">") | 1533 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "</time></td><td class=\"c-sync\">") |
| 1424 | if templ_7745c5c3_Err != nil { | 1534 | if templ_7745c5c3_Err != nil { | ||
| 1425 | return templ_7745c5c3_Err | 1535 | return templ_7745c5c3_Err | ||
| 1426 | } | 1536 | } | ||
| 1427 | if r.Synced { | 1537 | if r.Synced { | ||
| 1428 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "yes") | 1538 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, "yes") |
| 1429 | if templ_7745c5c3_Err != nil { | 1539 | if templ_7745c5c3_Err != nil { | ||
| 1430 | return templ_7745c5c3_Err | 1540 | return templ_7745c5c3_Err | ||
| 1431 | } | 1541 | } | ||
| 1432 | } else { | 1542 | } else { | ||
| 1433 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "no") | 1543 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "no") |
| 1434 | if templ_7745c5c3_Err != nil { | 1544 | if templ_7745c5c3_Err != nil { | ||
| 1435 | return templ_7745c5c3_Err | 1545 | return templ_7745c5c3_Err | ||
| 1436 | } | 1546 | } | ||
| 1437 | } | 1547 | } | ||
| 1438 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "</td><td class=\"c-act\"><form method=\"post\" action=\"") | 1548 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "</td><td class=\"c-act\"><form method=\"post\" action=\"") |
| 1439 | if templ_7745c5c3_Err != nil { | 1549 | if templ_7745c5c3_Err != nil { | ||
| 1440 | return templ_7745c5c3_Err | 1550 | return templ_7745c5c3_Err | ||
| 1441 | } | 1551 | } | ||
| 1442 | - | var templ_7745c5c3_Var71 templ.SafeURL | 1552 | + | var templ_7745c5c3_Var79 templ.SafeURL |
| 1443 | - | templ_7745c5c3_Var71, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove)) | 1553 | + | templ_7745c5c3_Var79, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(r.Remove)) |
| 1444 | if templ_7745c5c3_Err != nil { | 1554 | if templ_7745c5c3_Err != nil { | ||
| 1445 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 293, Col: 60} | 1555 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 301, Col: 60} |
| 1446 | } | 1556 | } | ||
| 1447 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var71)) | 1557 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var79)) |
| 1448 | if templ_7745c5c3_Err != nil { | 1558 | if templ_7745c5c3_Err != nil { | ||
| 1449 | return templ_7745c5c3_Err | 1559 | return templ_7745c5c3_Err | ||
| 1450 | } | 1560 | } | ||
| 1451 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"") | 1561 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\"><button type=\"submit\" class=\"btn danger\" aria-label=\"") |
| 1452 | if templ_7745c5c3_Err != nil { | 1562 | if templ_7745c5c3_Err != nil { | ||
| 1453 | return templ_7745c5c3_Err | 1563 | return templ_7745c5c3_Err | ||
| 1454 | } | 1564 | } | ||
| 1455 | - | var templ_7745c5c3_Var72 string | 1565 | + | var templ_7745c5c3_Var80 string |
| 1456 | - | templ_7745c5c3_Var72, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name) | 1566 | + | templ_7745c5c3_Var80, templ_7745c5c3_Err = templ.ResolveAttributeValue("Remove passkey " + r.Name) |
| 1457 | if templ_7745c5c3_Err != nil { | 1567 | if templ_7745c5c3_Err != nil { | ||
| 1458 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 294, Col: 89} | 1568 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 302, Col: 89} |
| 1459 | } | 1569 | } | ||
| 1460 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var72) | 1570 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var80) |
| 1461 | if templ_7745c5c3_Err != nil { | 1571 | if templ_7745c5c3_Err != nil { | ||
| 1462 | return templ_7745c5c3_Err | 1572 | return templ_7745c5c3_Err | ||
| 1463 | } | 1573 | } | ||
| 1464 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "\">Remove</button></form></td></tr>") | 1574 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, "\">Remove</button></form></td></tr>") |
| 1465 | if templ_7745c5c3_Err != nil { | 1575 | if templ_7745c5c3_Err != nil { | ||
| 1466 | return templ_7745c5c3_Err | 1576 | return templ_7745c5c3_Err | ||
| 1467 | } | 1577 | } | ||
| 1468 | } | 1578 | } | ||
| 1469 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "</tbody></table>") | 1579 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 123, "</tbody></table>") |
| 1470 | if templ_7745c5c3_Err != nil { | 1580 | if templ_7745c5c3_Err != nil { | ||
| 1471 | return templ_7745c5c3_Err | 1581 | return templ_7745c5c3_Err | ||
| 1472 | } | 1582 | } | ||
| 1473 | } else { | 1583 | } else { | ||
| 1474 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "<p class=\"lede dim\">no passkeys yet.</p>") | 1584 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 124, "<p class=\"lede dim\">no passkeys yet.</p>") |
| 1475 | if templ_7745c5c3_Err != nil { | 1585 | if templ_7745c5c3_Err != nil { | ||
| 1476 | return templ_7745c5c3_Err | 1586 | return templ_7745c5c3_Err | ||
| 1477 | } | 1587 | } | ||
| 1478 | } | 1588 | } | ||
| 1479 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, " ") | 1589 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 125, " ") |
| 1480 | if templ_7745c5c3_Err != nil { | 1590 | if templ_7745c5c3_Err != nil { | ||
| 1481 | return templ_7745c5c3_Err | 1591 | return templ_7745c5c3_Err | ||
| 1482 | } | 1592 | } | ||
| 1483 | if p.Full { | 1593 | if p.Full { | ||
| 1484 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "<p class=\"dim\">") | 1594 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, "<p class=\"dim\">") |
| 1485 | if templ_7745c5c3_Err != nil { | 1595 | if templ_7745c5c3_Err != nil { | ||
| 1486 | return templ_7745c5c3_Err | 1596 | return templ_7745c5c3_Err | ||
| 1487 | } | 1597 | } | ||
| 1488 | - | var templ_7745c5c3_Var73 string | 1598 | + | var templ_7745c5c3_Var81 string |
| 1489 | - | templ_7745c5c3_Var73, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max)) | 1599 | + | templ_7745c5c3_Var81, templ_7745c5c3_Err = templ.JoinStringErrs(itoa(p.Max)) |
| 1490 | if templ_7745c5c3_Err != nil { | 1600 | if templ_7745c5c3_Err != nil { | ||
| 1491 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 305, Col: 31} | 1601 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 313, Col: 31} |
| 1492 | } | 1602 | } | ||
| 1493 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var73)) | 1603 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var81)) |
| 1494 | if templ_7745c5c3_Err != nil { | 1604 | if templ_7745c5c3_Err != nil { | ||
| 1495 | return templ_7745c5c3_Err | 1605 | return templ_7745c5c3_Err | ||
| 1496 | } | 1606 | } | ||
| 1497 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 118, " passkeys are registered, the most there can be. Remove one to add another.</p>") | 1607 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, " passkeys are registered, the most there can be. Remove one to add another.</p>") |
| 1498 | if templ_7745c5c3_Err != nil { | 1608 | if templ_7745c5c3_Err != nil { | ||
| 1499 | return templ_7745c5c3_Err | 1609 | return templ_7745c5c3_Err | ||
| 1500 | } | 1610 | } | ||
| 1501 | } else { | 1611 | } else { | ||
| 1502 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 119, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"") | 1612 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 128, "<form class=\"passkey-add\" data-js data-passkey-form><label for=\"passkey-name\" class=\"sr\">Name of the new passkey</label> <input id=\"passkey-name\" type=\"text\" placeholder=\"Name, for example Pixel 9\" autocomplete=\"off\" data-passkey-name> <button type=\"submit\" class=\"btn primary\" data-passkey=\"register\" data-begin=\"") |
| 1503 | if templ_7745c5c3_Err != nil { | 1613 | if templ_7745c5c3_Err != nil { | ||
| 1504 | return templ_7745c5c3_Err | 1614 | return templ_7745c5c3_Err | ||
| 1505 | } | 1615 | } | ||
| 1506 | - | var templ_7745c5c3_Var74 string | 1616 | + | var templ_7745c5c3_Var82 string |
| 1507 | - | templ_7745c5c3_Var74, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) | 1617 | + | templ_7745c5c3_Var82, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Begin) |
| 1508 | if templ_7745c5c3_Err != nil { | 1618 | if templ_7745c5c3_Err != nil { | ||
| 1509 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 90} | 1619 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 90} |
| 1510 | } | 1620 | } | ||
| 1511 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var74) | 1621 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var82) |
| 1512 | if templ_7745c5c3_Err != nil { | 1622 | if templ_7745c5c3_Err != nil { | ||
| 1513 | return templ_7745c5c3_Err | 1623 | return templ_7745c5c3_Err | ||
| 1514 | } | 1624 | } | ||
| 1515 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 120, "\" data-finish=\"") | 1625 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "\" data-finish=\"") |
| 1516 | if templ_7745c5c3_Err != nil { | 1626 | if templ_7745c5c3_Err != nil { | ||
| 1517 | return templ_7745c5c3_Err | 1627 | return templ_7745c5c3_Err | ||
| 1518 | } | 1628 | } | ||
| 1519 | - | var templ_7745c5c3_Var75 string | 1629 | + | var templ_7745c5c3_Var83 string |
| 1520 | - | templ_7745c5c3_Var75, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) | 1630 | + | templ_7745c5c3_Var83, templ_7745c5c3_Err = templ.ResolveAttributeValue(p.Finish) |
| 1521 | if templ_7745c5c3_Err != nil { | 1631 | if templ_7745c5c3_Err != nil { | ||
| 1522 | - | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 310, Col: 115} | 1632 | + | return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/adapters/web/pages.templ`, Line: 318, Col: 115} |
| 1523 | } | 1633 | } | ||
| 1524 | - | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var75) | 1634 | + | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var83) |
| 1525 | if templ_7745c5c3_Err != nil { | 1635 | if templ_7745c5c3_Err != nil { | ||
| 1526 | return templ_7745c5c3_Err | 1636 | return templ_7745c5c3_Err | ||
| 1527 | } | 1637 | } | ||
| 1528 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "\">Add a passkey</button></form>") | 1638 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 130, "\">Add a passkey</button></form>") |
| 1529 | if templ_7745c5c3_Err != nil { | 1639 | if templ_7745c5c3_Err != nil { | ||
| 1530 | return templ_7745c5c3_Err | 1640 | return templ_7745c5c3_Err | ||
| 1531 | } | 1641 | } | ||
| 1532 | } | 1642 | } | ||
| 1533 | - | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 122, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") | 1643 | + | templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, " <p class=\"dim\" role=\"status\" aria-live=\"polite\" data-passkey-status></p>") |
| 1534 | if templ_7745c5c3_Err != nil { | 1644 | if templ_7745c5c3_Err != nil { | ||
| 1535 | return templ_7745c5c3_Err | 1645 | return templ_7745c5c3_Err | ||
| 1536 | } | 1646 | } | ||
| 1537 | return nil | 1647 | return nil | ||
| 1538 | }) | 1648 | }) | ||
| 1539 | - | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var64), templ_7745c5c3_Buffer) | 1649 | + | templ_7745c5c3_Err = Shell(l, nil).Render(templ.WithChildren(ctx, templ_7745c5c3_Var72), templ_7745c5c3_Buffer) |
| 1540 | if templ_7745c5c3_Err != nil { | 1650 | if templ_7745c5c3_Err != nil { | ||
| 1541 | return templ_7745c5c3_Err | 1651 | return templ_7745c5c3_Err | ||
| 1542 | } | 1652 | } | ||
M internal/adapters/web/releases.templ +16 -9
| @@ -40,15 +40,22 @@ templ Releases(l Layout, p ReleaseListPage) { | |||
| 40 | 40 | ||
| 41 | 41 | templ ReleaseDetail(l Layout, p ReleaseDetailPage) { | |
| 42 | 42 | @Shell(l, nil) { | |
| 43 | - | <h1>{ p.Title }</h1> | |
| 44 | - | <p> | |
| 45 | - | <span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow) | |
| 46 | - | if p.SHA != "" { | |
| 47 | - | <a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a> | |
| 48 | - | } | |
| 49 | - | <span class="dim">{ p.Published }</span> | |
| 50 | - | </p> | |
| 51 | - | <div class="md">@templ.Raw(string(p.Notes))</div> | |
| 43 | + | <section class="mr-card"> | |
| 44 | + | <header class="show mr-h"> | |
| 45 | + | <h1>{ p.Title }</h1> | |
| 46 | + | <dl class="kv show-kv"> | |
| 47 | + | <dt>tag</dt> | |
| 48 | + | <dd><span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow)</dd> | |
| 49 | + | if p.SHA != "" { | |
| 50 | + | <dt>commit</dt> | |
| 51 | + | <dd><a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a></dd> | |
| 52 | + | } | |
| 53 | + | <dt>published</dt> | |
| 54 | + | <dd>{ p.Published }</dd> | |
| 55 | + | </dl> | |
| 56 | + | </header> | |
| 57 | + | <article class="mr-desc prose">@templ.Raw(string(p.Notes))</article> | |
| 58 | + | </section> | |
| 52 | 59 | <h2>Assets</h2> | |
| 53 | 60 | if len(p.Assets) == 0 { | |
| 54 | 61 | <p class="dim">no assets.</p> | |
| @@ -40,15 +40,22 @@ templ Releases(l Layout, p ReleaseListPage) { | |||||
| 40 | 40 | ||||
| 41 | templ ReleaseDetail(l Layout, p ReleaseDetailPage) { | 41 | templ ReleaseDetail(l Layout, p ReleaseDetailPage) { | ||
| 42 | @Shell(l, nil) { | 42 | @Shell(l, nil) { | ||
| 43 | - | <h1>{ p.Title }</h1> | 43 | + | <section class="mr-card"> |
| 44 | - | <p> | 44 | + | <header class="show mr-h"> |
| 45 | - | <span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow) | 45 | + | <h1>{ p.Title }</h1> |
| 46 | - | if p.SHA != "" { | 46 | + | <dl class="kv show-kv"> |
| 47 | - | <a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a> | 47 | + | <dt>tag</dt> |
| 48 | - | } | 48 | + | <dd><span class="pill">{ p.Tag }</span> @ReleaseBadges(p.ReleaseRow)</dd> |
| 49 | - | <span class="dim">{ p.Published }</span> | 49 | + | if p.SHA != "" { |
| 50 | - | </p> | 50 | + | <dt>commit</dt> |
| 51 | - | <div class="md">@templ.Raw(string(p.Notes))</div> | 51 | + | <dd><a href={ templ.SafeURL(p.CommitHref) }><code>{ p.SHA }</code></a></dd> |
| 52 | + | } | |||
| 53 | + | <dt>published</dt> | |||
| 54 | + | <dd>{ p.Published }</dd> | |||
| 55 | + | </dl> | |||
| 56 | + | </header> | |||
| 57 | + | <article class="mr-desc prose">@templ.Raw(string(p.Notes))</article> | |||
| 58 | + | </section> | |||
| 52 | <h2>Assets</h2> | 59 | <h2>Assets</h2> | ||
| 53 | if len(p.Assets) == 0 { | 60 | if len(p.Assets) == 0 { | ||
| 54 | <p class="dim">no assets.</p> | 61 | <p class="dim">no assets.</p> | ||
M internal/adapters/web/releases_templ.go +32 -28
M internal/adapters/web/releases_test.go +12 -2
M internal/adapters/web/repo.go +4 -4
M internal/adapters/web/shell.templ +2 -3
M internal/adapters/web/shell_templ.go +48 -61
M internal/adapters/web/static/js/ermite.js +13 -4
M internal/adapters/web/static/js/mr.js +2 -2
M internal/adapters/web/summary.go +21 -0
A internal/adapters/web/summary_releases_test.go +49 -0
M internal/adapters/web/view.go +7 -1
M internal/app/testdata/web/blob-binary.html +33 -30
M internal/app/testdata/web/blob-code.html +33 -30
M internal/app/testdata/web/blob-empty.html +33 -30
M internal/app/testdata/web/blob-image.html +33 -30
M internal/app/testdata/web/blob-markdown.html +33 -30
M internal/app/testdata/web/blob-svg.html +33 -30
M internal/app/testdata/web/blob-text.html +33 -30
M internal/app/testdata/web/blob-too-large.html +33 -30
M internal/app/testdata/web/blob-trojan.html +33 -30
M internal/app/testdata/web/commit-big.html +33 -30
M internal/app/testdata/web/commit-binary.html +33 -30
M internal/app/testdata/web/commit-merge.html +33 -30
M internal/app/testdata/web/commit-modify-split.html +33 -30
M internal/app/testdata/web/commit-modify.html +33 -30
M internal/app/testdata/web/commit-rename.html +33 -30
M internal/app/testdata/web/commit-root.html +33 -30
M internal/app/testdata/web/commit-trojan.html +33 -30
M internal/app/testdata/web/commits-page2.html +33 -30
M internal/app/testdata/web/commits-path.html +33 -30
M internal/app/testdata/web/commits-root.html +33 -30
M internal/app/testdata/web/commits-small.html +33 -30
M internal/app/testdata/web/empty.html +12 -9
M internal/app/testdata/web/home.html +12 -9
M internal/app/testdata/web/not-found-page.html +12 -9
M internal/app/testdata/web/not-found.html +12 -9
M internal/app/testdata/web/refs.html +33 -30
M internal/app/testdata/web/summary.html +33 -30
M internal/app/testdata/web/tree-nested.html +33 -30
M internal/app/testdata/web/tree-root.html +33 -30
M internal/app/testdata/web/tree-slash-ref.html +33 -30
M internal/app/testdata/web/tree-subdir.html +33 -30
M internal/app/web_issue_test.go +1 -1
M internal/app/web_mr_test.go +1 -1
M internal/ports/mocks/ReleaseStore.go +66 -0
M internal/ports/release.go +3 -0
M internal/usecase/releases.go +25 -9
M internal/usecase/releases_integration_test.go +59 -0
A internal/usecase/releases_write_test.go +27 -0
Comments0 open / 0
no comments yet.