Public: anyone can read this; the crew can change it.
The family and chain pages' lineage lists draw §5's row #4635
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/4611-the-family-and-chain-pages-lineage-lists → main 1 commit fork
2 files
changed +19
−34
src/web/pages/following.ts +16 −32
| @@ -40,7 +40,7 @@ import { loadRepo, notFoundPage, repoBase, signInFirst } from "../chrome.ts"; | ||
| 40 | 40 | import { convergeWords, takeOrTell } from "../../actions/follow.ts"; |
| 41 | 41 | import { openProposal, proposeUpstream } from "../../actions/upstream.ts"; |
| 42 | 42 | import { field, readForm } from "../form.ts"; |
| 43 | import { html, raw, when, type Html } from "../html.ts"; | |
| 43 | import { html, when, type Html } from "../html.ts"; | |
| 44 | 44 | import { flashOrJson } from "../layout.ts"; |
| 45 | 45 | import { badge, btn, card, icon, row, type Tone } from "../ui.ts"; |
| 46 | 46 | import { disconnectedOn } from "./frozen.ts"; |
| @@ -54,39 +54,23 @@ import { disconnectedOn } from "./frozen.ts"; | ||
| 54 | 54 | export function lineageCard(lineage: Lineage, hereId: string): Html { |
| 55 | 55 | const node = (n: LineageNode, depth: number): Html => { |
| 56 | 56 | const here = n.repo.id === hereId; |
| 57 | const name = `${n.repo.ownerName}/${n.repo.name}`; | |
| 58 | return html`<li> | |
| 59 | <a | |
| 60 | href="/${n.repo.ownerName}/${n.repo.name}" | |
| 61 | class="row" | |
| 62 | data-nav | |
| 63 | tabindex="-1" | |
| 64 | ${here ? raw('aria-current="page"') : null} | |
| 65 | > | |
| 66 | <span class="row-lead">${icon(depth === 0 ? "repo" : "fork")}</span> | |
| 67 | <span class="row-main"> | |
| 68 | <span class="row-title" | |
| 69 | >${name}${here | |
| 70 | ? html` <span class="lineage-here">you are here</span>` | |
| 71 | : null}</span | |
| 72 | > | |
| 73 | ${n.repo.description === "" | |
| 74 | ? null | |
| 75 | : html`<span class="row-meta">${n.repo.description}</span>`} | |
| 76 | </span> | |
| 77 | ${n.relation === undefined | |
| 78 | ? null | |
| 79 | : html`<span class="row-trail">${relationBadge(n.relation)}</span>`} | |
| 80 | </a> | |
| 81 | ${n.children.length === 0 | |
| 82 | ? null | |
| 83 | : html`<ul class="lineage-children"> | |
| 84 | ${n.children.map((c) => node(c, depth + 1))} | |
| 85 | </ul>`} | |
| 86 | </li>`; | |
| 57 | const trail = [ | |
| 58 | here ? badge("you are here", { variant: "outline" }) : null, | |
| 59 | n.relation === undefined ? null : relationBadge(n.relation), | |
| 60 | ].filter((t): t is Html => t !== null); | |
| 61 | return row({ | |
| 62 | href: `/${n.repo.ownerName}/${n.repo.name}`, | |
| 63 | nav: true, | |
| 64 | current: here, | |
| 65 | lead: icon(depth === 0 ? "repo" : "fork"), | |
| 66 | title: `${n.repo.ownerName}/${n.repo.name}`, | |
| 67 | ...(n.repo.description === "" ? {} : { meta: html`${n.repo.description}` }), | |
| 68 | ...(trail.length === 0 ? {} : { trail: html`${trail}` }), | |
| 69 | children: n.children.map((c) => node(c, depth + 1)), | |
| 70 | }); | |
| 87 | 71 | }; |
| 88 | 72 | return card( |
| 89 | html`<ul class="list lineage" aria-label="Forks, by who follows whom"> | |
| 73 | html`<ul class="list" aria-label="Forks, by who follows whom"> | |
| 90 | 74 | ${node(lineage.root, 0)} |
| 91 | 75 | </ul> |
| 92 | 76 | ${when( |
test/following.test.ts +3 −2
| @@ -730,11 +730,12 @@ describe("a fork that follows its parent", () => { | ||
| 730 | 730 | expect(page).toContain("fay/game-fay"); |
| 731 | 731 | expect(page).toMatch( |
| 732 | 732 | new RegExp( |
| 733 | `aria-current="page"[\\s\\S]{0,2000}${here}[\\s\\S]{0,80}you are here`, | |
| 733 | `aria-current="true"[\\s\\S]{0,2000}${here}[\\s\\S]{0,600}you are here`, | |
| 734 | 734 | ), |
| 735 | 735 | ); |
| 736 | expect(page).not.toMatch(/class="[^"]*\blineage(-children|-here)?\b/); | |
| 736 | 737 | const bobAt = page.indexOf('href="/bob/game"'); |
| 737 | const nested = page.indexOf("lineage-children", bobAt); | |
| 738 | const nested = page.indexOf("row-children", bobAt); | |
| 738 | 739 | const fayAt = page.indexOf('href="/fay/game-fay"'); |
| 739 | 740 | expect(bobAt).toBeGreaterThan(-1); |
| 740 | 741 | expect(nested).toBeGreaterThan(bobAt); |
new above
offline