Public: anyone can read this; the crew can change it.
The front page's crew line, live mark, issue list and more line draw §5's row, listCard and dot, and .front-crew, .front-live, .front-issues, .front-more leave the markup #4161
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/4140-the-front-page-s-crew-line-live-mark-iss → main 1 commit fork
2 files
changed +35
−22
src/web/studio/home.ts +32 −22
| @@ -33,10 +33,12 @@ import { liveClientJs } from "../live.ts"; | ||
| 33 | 33 | import { |
| 34 | 34 | btn, |
| 35 | 35 | card, |
| 36 | dot, | |
| 36 | 37 | empty, |
| 37 | 38 | envStateBadge, |
| 38 | 39 | icon, |
| 39 | 40 | listCard, |
| 41 | row, | |
| 40 | 42 | timeAgo, |
| 41 | 43 | } from "../ui.ts"; |
| 42 | 44 | import { |
| @@ -342,26 +344,29 @@ function featuredCard(featured: NonNullable<FrontPage["featured"]>): Html { | ||
| 342 | 344 | const agents = `${crew.running} agent${crew.running === 1 ? "" : "s"}`; |
| 343 | 345 | const work = |
| 344 | 346 | crew.running > 0 |
| 345 | ? html`<p class="front-crew"> | |
| 346 | <span class="front-live" aria-hidden="true"></span> | |
| 347 | The crew is at work: ${agents} right now | |
| 348 | </p> | |
| 349 | <ul class="front-issues"> | |
| 350 | ${crew.issues.map( | |
| 351 | (i) => | |
| 352 | html`<li> | |
| 353 | <a href="${base}/issues/${i.number}" | |
| 354 | ><span class="muted">#${i.number}</span> ${i.title}</a | |
| 355 | > | |
| 356 | </li>`, | |
| 357 | )} | |
| 358 | </ul>` | |
| 347 | ? listCard([ | |
| 348 | row({ | |
| 349 | lead: dot("success"), | |
| 350 | title: `The crew is at work: ${agents} right now`, | |
| 351 | }), | |
| 352 | ...crew.issues.map((i) => | |
| 353 | row({ | |
| 354 | href: `${base}/issues/${i.number}`, | |
| 355 | lead: html`<span class="muted">#${i.number}</span>`, | |
| 356 | title: i.title, | |
| 357 | }), | |
| 358 | ), | |
| 359 | ]) | |
| 359 | 360 | : signals.shippedAt !== null |
| 360 | ? html`<p class="front-crew muted"> | |
| 361 | Shipped ${timeAgo(signals.shippedAt)}${signals.ships > 0 | |
| 362 | ? ` · ${signals.ships} change${signals.ships === 1 ? "" : "s"} merged this month` | |
| 363 | : ""} | |
| 364 | </p>` | |
| 361 | ? listCard([ | |
| 362 | row({ | |
| 363 | title: `Shipped ${timeAgo(signals.shippedAt)}${ | |
| 364 | signals.ships > 0 | |
| 365 | ? ` · ${signals.ships} change${signals.ships === 1 ? "" : "s"} merged this month` | |
| 366 | : "" | |
| 367 | }`, | |
| 368 | }), | |
| 369 | ]) | |
| 365 | 370 | : null; |
| 366 | 371 | return html`<section class="front-featured" aria-label="Featured"> |
| 367 | 372 | ${when( |
| @@ -542,9 +547,14 @@ export function studioDoor(ctx: Ctx): Response { | ||
| 542 | 547 | ${when( |
| 543 | 548 | front.total > tiles.length + (front.featured === undefined ? 0 : 1), |
| 544 | 549 | () => |
| 545 | html`<p class="mt front-more"> | |
| 546 | <a href="/explore?q=kind%3Aapp">All ${front.total} public apps</a> | |
| 547 | </p>`, | |
| 550 | html`<div class="mt"> | |
| 551 | ${listCard([ | |
| 552 | row({ | |
| 553 | href: "/explore?q=kind%3Aapp", | |
| 554 | title: `All ${front.total} public apps`, | |
| 555 | }), | |
| 556 | ])} | |
| 557 | </div>`, | |
| 548 | 558 | )}` |
| 549 | 559 | : front.featured === undefined |
| 550 | 560 | ? html`<div class="mt"> |
test/front.test.ts +3
| @@ -550,6 +550,9 @@ describe("the front page", () => { | ||
| 550 | 550 | const body = await door(); |
| 551 | 551 | expect(body).toContain("The crew is at work: 1 agent right now"); |
| 552 | 552 | expect(body).toContain("Make the board faster"); |
| 553 | expect(body).toContain(`href="/owner/two/issues/${issue.value.number}"`); | |
| 554 | for (const old of ["front-crew", "front-live", "front-issues", "front-more"]) | |
| 555 | expect(body).not.toContain(old); | |
| 553 | 556 | const json = (await (await fetch(`${base}/api/v1/front`)).json()) as any; |
| 554 | 557 | expect(json.featured.crew).toEqual({ |
| 555 | 558 | running: 1, |
new above
offline